diff options
author | Timm Friebe <thekid@thekid.de> | 2014-07-06 17:07:01 +0200 |
---|---|---|
committer | Timm Friebe <thekid@thekid.de> | 2014-07-06 17:07:01 +0200 |
commit | a1554ca6343598c38e4fb4fbcc46419ce0bdf058 (patch) | |
tree | e66e73ff23a340cf7343459a0331a57b8eff65aa | |
parent | e0d51d1cf00d43c57104764b620bb9219889a86d (diff) | |
parent | 5b925824edf3edc951fc41608d5cbd07a0baab08 (diff) | |
download | php-git-a1554ca6343598c38e4fb4fbcc46419ce0bdf058.tar.gz |
Merge in changes from master
Now also includes "on [TYPE]" in "Call to a member function" error
409 files changed, 13503 insertions, 4506 deletions
diff --git a/.gitignore b/.gitignore index 8d0e7565f2..b9dd252267 100644 --- a/.gitignore +++ b/.gitignore @@ -246,6 +246,8 @@ sapi/fpm/php-fpm.1 sapi/fpm/init.d.php-fpm sapi/fpm/php-fpm.conf sapi/fpm/fpm/php-cgi +sapi/phpdbg/phpdbg_parser.c +sapi/phpdbg/phpdbg_parser.h sapi/phpdbg/phpdbg scripts/php-config scripts/phpize diff --git a/.travis.yml b/.travis.yml index 07653040dd..8de7ee852d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,8 @@ php: - 5.4 notifications: - email: false + email: + on_failure: change env: global: @@ -15,9 +16,14 @@ env: - PDO_MYSQL_TEST_USER=travis - PDO_MYSQL_TEST_PASS= - PDO_MYSQL_TEST_HOST=127.0.0.1 - matrix: - REPORT_EXIT_STATUS=1 + matrix: + - ENABLE_MAINTAINER_ZTS=0 ENABLE_DEBUG=0 + - ENABLE_MAINTAINER_ZTS=1 ENABLE_DEBUG=1 +before_install: + - sudo apt-get update -qq + - sudo apt-get install -y libenchant-dev libaspell-dev libpspell-dev librecode-dev before_script: # Compile PHP - ./travis/compile.sh @@ -29,4 +35,6 @@ before_script: - . ./travis/ext/pdo_pgsql/setup.sh # Run PHPs run-tests.php -script: ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --show-diff --set-timeout 120 +script: + - ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --show-diff --set-timeout 120 + - ./sapi/cli/php sapi/phpdbg/tests/run-tests.php -diff2stdout --phpdbg sapi/phpdbg/phpdbg @@ -1,6 +1,6 @@ -------------------------------------------------------------------- The PHP License, version 3.01 -Copyright (c) 1999 - 2012 The PHP Group. All rights reserved. +Copyright (c) 1999 - 2014 The PHP Group. All rights reserved. -------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without diff --git a/Makefile.gcov b/Makefile.gcov index 37c1b4b44c..8d30f34ae8 100644 --- a/Makefile.gcov +++ b/Makefile.gcov @@ -14,7 +14,7 @@ php_lcov.info: lcov-test @rm -rf lcov_data/ @$(mkinstalldirs) lcov_data/ @echo - -@files=`find . -name \*.gcda -o -name \*.gcno -o -name \*.da -o -name \*.c -o -name \*.h | sed -e 's/^\.\///' | sed -e 's/\.gcda//g' -e 's/\.gcno//g' -e 's/\.da//g' | $(EGREP) $(LCOV_INCLUDE) | uniq` ;\ + -@files=`find . -name \*.gcda -o -name \*.gcno -o -name \*.da -o -name \*.c -o -name \*.h | sed -e 's/^\.\///' | sed -e 's/\.gcda//g' -e 's/\.gcno//g' -e 's/\.da//g' | $(EGREP) $(LCOV_INCLUDE) | sed -e 's/.libs/zzzz/g' | sort | sed -e 's/zzzz/.libs/g' | uniq` ;\ for x in $$files; do \ echo -n . ;\ y=`echo $$x | sed -e 's!\.libs/!!'`; \ @@ -2,6 +2,11 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 20??, PHP 5.7.0 +- CLI server: + . Refactor MIME type handling to use a hash table instead of linear search. + (Adam) + . Update the MIME type list from the one shipped by Apache HTTPD. (Adam) + - DBA: . Fixed bug #62490 (dba_delete returns true on missing item (inifile)). (Mike) diff --git a/README.RELEASE_PROCESS b/README.RELEASE_PROCESS index 21305f2993..7a82a5c614 100644 --- a/README.RELEASE_PROCESS +++ b/README.RELEASE_PROCESS @@ -11,17 +11,27 @@ because the sysadmins can not upgrade stuff then. 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 (David/Julien/ +3. Ensure that the tests on Travis CI are green. +See: https://travis-ci.org/php/php-src/builds +It is recommended to do so a couple of days before the packaging day, to +have enough time to investigate failures, communicate with the authors and +commit the fixes. +The RM for the branch is also responsible for keeping the CI green on +ongoing bases between the releases. Check the CI status for your branch +periodically and resolve the failures ASAP. See more in: +https://wiki.php.net/rfc/travis_ci + +4. Ensure that Windows builds will work before packaging + +5. 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. +6. Verify the tags to be extra sure everything was tagged properly. -6. Moving extensions from/to PECL requires write acces to the destination. +7. Moving extensions from/to PECL requires write acces to the destination. Most developers should have this. Moving extensions from php-src to PECL @@ -48,47 +58,49 @@ Rolling a non stable release (alpha/beta/RC) 1. Check windows snapshot builder logs (http://windows.php.net/downloads/snaps/ the last revision) -2. run the "scripts/dev/credits" script in php-src and commit the changes in the +2. Check the tests at https://travis-ci.org/php/php-src/builds + +3. 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) from the main branch. +4. 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``. +5. 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 dashes, you should ``#define PHP_VERSION "5.4.22RC1"`` and not ``#define PHP_VERSION "5.4.22-RC1"`` -5. Compile and make test, with and without ZTS, using the right Bison version +6. 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. Check ./sapi/cli/php -v output for version matching. +7. 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. 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.: +9. Tag the repository release branch with the version, e.g.: ``git tag -u YOURKEYID php-5.4.2RC2`` -9. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and ``NEWS`` +10. 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 : +11. 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}`` -11. run: ``PHPROOT=. ./makedist 5.4.2RC2``, this will export the tree, create configure +12. run: ``PHPROOT=. ./makedist 5.4.2RC2``, this will export the tree, create configure and build three tarballs (gz, bz2 and xz). -12. Copy those tarballs (scp, rsync) to downloads.php.net, in your homedir there should be a +13. 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 or Dan. -13. Now the RC can be found on http://downloads.php.net/yourname, +14. Now the RC can be found on http://downloads.php.net/yourname, f.e. http://downloads.php.net/derick/ -14. Once the release has been tagged, contact the PHP Windows development team +15. 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. @@ -144,7 +156,8 @@ 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. -3. Commit those changes +3. Commit those changes. Ensure the tests at https://travis-ci.org/php/php-src/builds are +still passing. 4. run the "scripts/dev/credits" script in php-src and commit the changes in the credits files in ext/standard. @@ -154,7 +167,7 @@ credits files in ext/standard. 6. Check ./sapi/cli/php -v output for version matching. -7. tag the repository with the version f.e. "``git tag -s php-5.4.1``" +7. tag the repository with the version f.e. "``git tag -u YOURKEYID -s php-5.4.1``" 8. Push the tag f.e. "``git push origin php-5.4.1``" diff --git a/README.namespaces b/README.namespaces index 9c427b634f..9c427b634f 100755..100644 --- a/README.namespaces +++ b/README.namespaces diff --git a/UPGRADING b/UPGRADING index 4c49485725..740047a86a 100755..100644 --- a/UPGRADING +++ b/UPGRADING @@ -4,16 +4,16 @@ PHP X.Y UPGRADE NOTES 1. Backward Incompatible Changes 2. New Features -2. Changes in SAPI modules -3. Deprecated Functionality -4. Changed Functions -5. New Functions -6. New Classes and Interfaces -7. Removed Extensions -8. Other Changes to Extensions -9. New Global Constants -10. Changes to INI File Handling -11. Other Changes +3. Changes in SAPI modules +4. Deprecated Functionality +5. Changed Functions +6. New Functions +7. New Classes and Interfaces +8. Removed Extensions +9. Other Changes to Extensions +10. New Global Constants +11. Changes to INI File Handling +12. Other Changes ======================================== @@ -30,52 +30,52 @@ PHP X.Y UPGRADE NOTES ======================================== -2. Changes in SAPI modules +3. Changes in SAPI modules ======================================== ======================================== -3. Deprecated Functionality +4. Deprecated Functionality ======================================== ======================================== -4. Changed Functions +5. Changed Functions ======================================== ======================================== -5. New Functions +6. New Functions ======================================== ======================================== -6. New Classes and Interfaces +7. New Classes and Interfaces ======================================== ======================================== -7. Removed Extensions +8. Removed Extensions ======================================== ======================================== -8. Other Changes to Extensions +9. Other Changes to Extensions ======================================== ======================================== -9. New Global Constants +10. New Global Constants ======================================== ======================================== -10. Changes to INI File Handling +11. Changes to INI File Handling ======================================== ======================================== -11. Other Changes +12. Other Changes ======================================== - Standard diff --git a/Zend/tests/67468.phpt b/Zend/tests/67468.phpt new file mode 100644 index 0000000000..767217644a --- /dev/null +++ b/Zend/tests/67468.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #67468 (Segfault in highlight_file()/highlight_string()) +--SKIPIF-- +<?php if(!function_exists("leak")) print "skip only for debug builds"; ?> +--FILE-- +<?php +highlight_string("<?php __CLASS__;", true); +echo "done"; +?> +--EXPECT-- +done diff --git a/Zend/tests/bug67169.phpt b/Zend/tests/bug67169.phpt new file mode 100644 index 0000000000..8aa6aaf24a --- /dev/null +++ b/Zend/tests/bug67169.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #67169: array_splice all elements, then []= gives wrong index +--FILE-- +<?php + +$array = array('a', 'b'); +array_splice($array, 0, 2); +$array[] = 'c'; +var_dump($array); + +$array = array('a', 'b'); +array_shift($array); +array_shift($array); +$array[] = 'c'; +var_dump($array); + +?> +--EXPECT-- +array(1) { + [0]=> + string(1) "c" +} +array(1) { + [0]=> + string(1) "c" +} diff --git a/Zend/tests/bug67368.phpt b/Zend/tests/bug67368.phpt new file mode 100644 index 0000000000..c92e994b94 --- /dev/null +++ b/Zend/tests/bug67368.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #67368 (Memory leak with immediately dereferenced array in class constant) +--INI-- +report_memleaks=1 +--FILE-- +<?php +class FooBar { + const bar = ["bar" => 3]["bar"]; +} +echo "okey"; +--EXPECTF-- +okey diff --git a/Zend/tests/bug67436/a.php b/Zend/tests/bug67436/a.php new file mode 100644 index 0000000000..c560c2db7d --- /dev/null +++ b/Zend/tests/bug67436/a.php @@ -0,0 +1,10 @@ +<?php + +class a { + public function test($arg = c::TESTCONSTANT) { + echo __METHOD__ . "($arg)\n"; + } + + static public function staticTest() { + } +} diff --git a/Zend/tests/bug67436/b.php b/Zend/tests/bug67436/b.php new file mode 100644 index 0000000000..793a1394d6 --- /dev/null +++ b/Zend/tests/bug67436/b.php @@ -0,0 +1,8 @@ +<?php + +class b extends a { + public function test() { + echo __METHOD__ . "()\n"; + parent::test(); + } +} diff --git a/Zend/tests/bug67436/bug67436.phpt b/Zend/tests/bug67436/bug67436.phpt new file mode 100644 index 0000000000..49b8b491d2 --- /dev/null +++ b/Zend/tests/bug67436/bug67436.phpt @@ -0,0 +1,26 @@ +--TEST-- +bug67436: Autoloader isn't called if user defined error handler is present + +--INI-- +error_reporting= + +--FILE-- +<?php + +spl_autoload_register(function($classname) { + if (in_array($classname, array('a','b','c'))) { + require_once ($classname . '.php'); + } +}); + +set_error_handler(function ($errno, $errstr, $errfile, $errline) { +}, error_reporting()); + +a::staticTest(); + +$b = new b(); +$b->test(); + +--EXPECT-- +b::test() +a::test(c::TESTCONSTANT) diff --git a/Zend/tests/bug67436/bug67436_nohandler.phpt b/Zend/tests/bug67436/bug67436_nohandler.phpt new file mode 100644 index 0000000000..464f711532 --- /dev/null +++ b/Zend/tests/bug67436/bug67436_nohandler.phpt @@ -0,0 +1,24 @@ +--TEST-- +bug67436: E_STRICT instead of custom error handler + +--INI-- +error_reporting=-1 + +--FILE-- +<?php + +spl_autoload_register(function($classname) { + if (in_array($classname, array('a','b','c'))) { + require_once ($classname . '.php'); + } +}); + +a::staticTest(); + +$b = new b(); +$b->test(); + +--EXPECTF-- +Strict Standards: Declaration of b::test() should be compatible with a::test($arg = c::TESTCONSTANT) in %s/bug67436/b.php on line %d +b::test() +a::test(c::TESTCONSTANT) diff --git a/Zend/tests/bug67436/c.php b/Zend/tests/bug67436/c.php new file mode 100644 index 0000000000..47c848bfa0 --- /dev/null +++ b/Zend/tests/bug67436/c.php @@ -0,0 +1,5 @@ +<?php + +class c { + const TESTCONSTANT = "c::TESTCONSTANT"; +} diff --git a/Zend/tests/closure_049.phpt b/Zend/tests/closure_049.phpt new file mode 100644 index 0000000000..684b33d564 --- /dev/null +++ b/Zend/tests/closure_049.phpt @@ -0,0 +1,22 @@ +--TEST-- +Closure 049: static::class in static closure in non-static method. + +--FILE-- +<?php + +class A { + function foo() { + $f = static function() { + return static::class; + }; + return $f(); + } +} + +class B extends A {} + +$b = new B; + +var_dump($b->foo()); +--EXPECT-- +string(1) "B" diff --git a/Zend/tests/closure_050.phpt b/Zend/tests/closure_050.phpt new file mode 100644 index 0000000000..d43f325ef1 --- /dev/null +++ b/Zend/tests/closure_050.phpt @@ -0,0 +1,22 @@ +--TEST-- +Closure 050: static::class in non-static closure in non-static method. + +--FILE-- +<?php + +class A { + function foo() { + $f = function() { + return static::class; + }; + return $f(); + } +} + +class B extends A {} + +$b = new B; +var_dump($b->foo()); + +--EXPECT-- +string(1) "B" diff --git a/Zend/tests/closure_051.phpt b/Zend/tests/closure_051.phpt new file mode 100644 index 0000000000..78b28d74a3 --- /dev/null +++ b/Zend/tests/closure_051.phpt @@ -0,0 +1,21 @@ +--TEST-- +Closure 051: static::class in static closure in static method. + +--FILE-- +<?php + +class A { + static function foo() { + $f = static function() { + return static::class; + }; + return $f(); + } +} + +class B extends A {} + +var_dump(B::foo()); + +--EXPECT-- +string(1) "B" diff --git a/Zend/tests/closure_052.phpt b/Zend/tests/closure_052.phpt new file mode 100644 index 0000000000..f878515a82 --- /dev/null +++ b/Zend/tests/closure_052.phpt @@ -0,0 +1,21 @@ +--TEST-- +Closure 052: static::class in non-static closure in static method. + +--FILE-- +<?php + +class A { + static function foo() { + $f = function() { + return static::class; + }; + return $f(); + } +} + +class B extends A {} + +var_dump(B::foo()); + +--EXPECT-- +string(1) "B" diff --git a/Zend/tests/closure_053.phpt b/Zend/tests/closure_053.phpt new file mode 100644 index 0000000000..b1d76a2561 --- /dev/null +++ b/Zend/tests/closure_053.phpt @@ -0,0 +1,22 @@ +--TEST-- +Closure 053: self::class in static closure in non-static method. + +--FILE-- +<?php + +class A { + function foo() { + $f = static function() { + return self::class; + }; + return $f(); + } +} + +class B extends A {} + +$b = new B; +var_dump($b->foo()); + +--EXPECT-- +string(1) "A" diff --git a/Zend/tests/closure_054.phpt b/Zend/tests/closure_054.phpt new file mode 100644 index 0000000000..b2f87d1d61 --- /dev/null +++ b/Zend/tests/closure_054.phpt @@ -0,0 +1,22 @@ +--TEST-- +Closure 054: self::class in non-static closure in non-static method. + +--FILE-- +<?php + +class A { + function foo() { + $f = function() { + return self::class; + }; + return $f(); + } +} + +class B extends A {} + +$b = new B; +var_dump($b->foo()); + +--EXPECT-- +string(1) "A" diff --git a/Zend/tests/closure_055.phpt b/Zend/tests/closure_055.phpt new file mode 100644 index 0000000000..047d72a89b --- /dev/null +++ b/Zend/tests/closure_055.phpt @@ -0,0 +1,21 @@ +--TEST-- +Closure 055: self::class in static closure in static method. + +--FILE-- +<?php + +class A { + static function foo() { + $f = static function() { + return self::class; + }; + return $f(); + } +} + +class B extends A {} + +var_dump(B::foo()); + +--EXPECT-- +string(1) "A" diff --git a/Zend/tests/closure_056.phpt b/Zend/tests/closure_056.phpt new file mode 100644 index 0000000000..566de10d83 --- /dev/null +++ b/Zend/tests/closure_056.phpt @@ -0,0 +1,21 @@ +--TEST-- +Closure 056: self::class in non-static closure in static method. + +--FILE-- +<?php + +class A { + static function foo() { + $f = function() { + return self::class; + }; + return $f(); + } +} + +class B extends A {} + +var_dump(B::foo()); + +--EXPECT-- +string(1) "A" diff --git a/Zend/tests/closure_bug66622.phpt b/Zend/tests/closure_bug66622.phpt new file mode 100644 index 0000000000..1c9577d688 --- /dev/null +++ b/Zend/tests/closure_bug66622.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug 66622: Closures do not correctly capture the late bound class (static::) in some cases + +--FILE-- +<?php +class A { + static function name() { return 'A'; } + function foo() { + $fn = function() { return static::name(); }; + echo static::name() . ' vs ' . $fn() . "\n"; + } + function bar() { + $fn = static function() { return static::name(); }; + echo static::name() . ' vs ' . $fn() . "\n"; + } + static function baz() { + $fn = function() { return static::name(); }; + echo static::name() . ' vs ' . $fn() . "\n"; + } +} +class B extends A { + static function name() { return 'B'; } +} + +function test() { + (new B)->foo(); + (new B)->bar(); + (new B)->baz(); + B::baz(); +} +test(); + +--EXPECT-- +B vs B +B vs B +B vs B +B vs B diff --git a/Zend/tests/constant_expressions_arrays.phpt b/Zend/tests/constant_expressions_arrays.phpt new file mode 100644 index 0000000000..061fcc6a92 --- /dev/null +++ b/Zend/tests/constant_expressions_arrays.phpt @@ -0,0 +1,35 @@ +--TEST-- +Constant expressions with arrays +--FILE-- +<?php +const a = [1,2,[3,[4]]]; +const b = a[0]; +const c = a[2][0]; +const d = a[2]; +const e = ["string" => [1]]["string"][0]; + +var_dump(b, c, e); + +function test ($a = d[1][0]) { + var_dump($a); +} + +test(); + +class foo { + const bar = [1][0]; +} + +var_dump(foo::bar); + +var_dump(a); // Eventually allow that later with array dereferencing of constants + +?> +--EXPECTF-- +int(1) +int(3) +int(1) +int(4) +int(1) + +Fatal error: Arrays are not allowed in constants at run-time in %s on line %d diff --git a/Zend/tests/constant_expressions_self_referencing_array.phpt b/Zend/tests/constant_expressions_self_referencing_array.phpt new file mode 100644 index 0000000000..09f862e048 --- /dev/null +++ b/Zend/tests/constant_expressions_self_referencing_array.phpt @@ -0,0 +1,15 @@ +--TEST-- +Self-referencing constant expression (part of a constant AST) +--XFAIL-- +Not yet fixed, to be fixed for PHP 5.6 +--FILE-- +<?php +class A { + const FOO = [self::BAR]; + const BAR = [self::FOO]; +} +var_dump(A::FOO); +?> +--EXPECTF-- +Fatal error: Cannot declare self-referencing constant 'self::FOO' in %s on line %d + diff --git a/Zend/tests/generators/bug67497.phpt b/Zend/tests/generators/bug67497.phpt new file mode 100644 index 0000000000..483857b96c --- /dev/null +++ b/Zend/tests/generators/bug67497.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #67467: eval with parse error causes segmentation fault in generator +--FILE-- +<?php + +function gen() { + $a = 1; + yield $a; +} + +@eval('abc'); + +$values = gen(); +$values->next(); + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/zend.c b/Zend/zend.c index acbbcbebc7..d735e4a9e7 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -954,7 +954,7 @@ ZEND_API void zend_deactivate(TSRMLS_D) /* {{{ */ zend_destroy_rsrc_list(&EG(regular_list) TSRMLS_CC); -#ifdef ZEND_DEBUG +#if ZEND_DEBUG if (GC_G(gc_enabled) && !CG(unclean_shutdown)) { gc_collect_cycles(TSRMLS_C); } diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index e486aa326c..fceb940fa3 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -328,8 +328,7 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s { zval *tmp; zend_fetch_dimension_by_zval(&tmp, &op1, &op2 TSRMLS_CC); - *result = *tmp; - efree(tmp); + ZVAL_ZVAL(result, tmp, 1, 1); } zval_dtor(&op1); zval_dtor(&op2); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 6bfb888988..d7a1b3710d 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -245,16 +245,16 @@ static const zend_function_entry builtin_functions[] = { /* {{{ */ ZEND_FE(func_num_args, arginfo_zend__void) ZEND_FE(func_get_arg, arginfo_func_get_arg) ZEND_FE(func_get_args, arginfo_zend__void) - ZEND_FE(strlen, arginfo_strlen) - ZEND_FE(strcmp, arginfo_strcmp) - ZEND_FE(strncmp, arginfo_strncmp) - ZEND_FE(strcasecmp, arginfo_strcmp) + ZEND_FE(strlen, arginfo_strlen) + ZEND_FE(strcmp, arginfo_strcmp) + ZEND_FE(strncmp, arginfo_strncmp) + ZEND_FE(strcasecmp, arginfo_strcmp) ZEND_FE(strncasecmp, arginfo_strncmp) - ZEND_FE(each, arginfo_each) + ZEND_FE(each, arginfo_each) ZEND_FE(error_reporting, arginfo_error_reporting) - ZEND_FE(define, arginfo_define) - ZEND_FE(defined, arginfo_defined) - ZEND_FE(get_class, arginfo_get_class) + ZEND_FE(define, arginfo_define) + ZEND_FE(defined, arginfo_defined) + ZEND_FE(get_class, arginfo_get_class) ZEND_FE(get_called_class, arginfo_zend__void) ZEND_FE(get_parent_class, arginfo_get_class) ZEND_FE(method_exists, arginfo_method_exists) @@ -274,13 +274,13 @@ static const zend_function_entry builtin_functions[] = { /* {{{ */ ZEND_FE(get_included_files, arginfo_zend__void) ZEND_FALIAS(get_required_files, get_included_files, arginfo_zend__void) ZEND_FE(is_subclass_of, arginfo_is_subclass_of) - ZEND_FE(is_a, arginfo_is_subclass_of) + ZEND_FE(is_a, arginfo_is_subclass_of) ZEND_FE(get_class_vars, arginfo_get_class_vars) ZEND_FE(get_object_vars, arginfo_get_object_vars) ZEND_FE(get_class_methods, arginfo_get_class_methods) ZEND_FE(trigger_error, arginfo_trigger_error) ZEND_FALIAS(user_error, trigger_error, arginfo_trigger_error) - ZEND_FE(set_error_handler, arginfo_set_error_handler) + ZEND_FE(set_error_handler, arginfo_set_error_handler) ZEND_FE(restore_error_handler, arginfo_zend__void) ZEND_FE(set_exception_handler, arginfo_set_exception_handler) ZEND_FE(restore_exception_handler, arginfo_zend__void) @@ -288,14 +288,14 @@ static const zend_function_entry builtin_functions[] = { /* {{{ */ ZEND_FE(get_declared_traits, arginfo_zend__void) ZEND_FE(get_declared_interfaces, arginfo_zend__void) ZEND_FE(get_defined_functions, arginfo_zend__void) - ZEND_FE(get_defined_vars, arginfo_zend__void) - ZEND_FE(create_function, arginfo_create_function) - ZEND_FE(get_resource_type, arginfo_get_resource_type) + ZEND_FE(get_defined_vars, arginfo_zend__void) + ZEND_FE(create_function, arginfo_create_function) + ZEND_FE(get_resource_type, arginfo_get_resource_type) ZEND_FE(get_loaded_extensions, arginfo_get_loaded_extensions) - ZEND_FE(extension_loaded, arginfo_extension_loaded) + ZEND_FE(extension_loaded, arginfo_extension_loaded) ZEND_FE(get_extension_funcs, arginfo_extension_loaded) ZEND_FE(get_defined_constants, arginfo_get_defined_constants) - ZEND_FE(debug_backtrace, arginfo_debug_backtrace) + ZEND_FE(debug_backtrace, arginfo_debug_backtrace) ZEND_FE(debug_print_backtrace, arginfo_debug_print_backtrace) #if ZEND_DEBUG ZEND_FE(zend_test_func, NULL) @@ -305,7 +305,7 @@ static const zend_function_entry builtin_functions[] = { /* {{{ */ #endif ZEND_FE(gc_collect_cycles, arginfo_zend__void) ZEND_FE(gc_enabled, arginfo_zend__void) - ZEND_FE(gc_enable, arginfo_zend__void) + ZEND_FE(gc_enable, arginfo_zend__void) ZEND_FE(gc_disable, arginfo_zend__void) ZEND_FE_END }; diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index d714b35b39..bd2ede329d 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -480,6 +480,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent } } + closure->this_ptr = NULL; /* Invariants: * If the closure is unscoped, it has no bound object. * The the closure is scoped, it's either static or it's bound */ @@ -491,10 +492,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent Z_ADDREF_P(this_ptr); } else { closure->func.common.fn_flags |= ZEND_ACC_STATIC; - closure->this_ptr = NULL; } - } else { - closure->this_ptr = NULL; } } /* }}} */ diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index beb53402ba..7c979d56b7 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3461,8 +3461,11 @@ static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{ *zv = *precv->op2.zv; zval_copy_ctor(zv); INIT_PZVAL(zv); - zval_update_constant_ex(&zv, 1, fptr->common.scope TSRMLS_CC); - if (Z_TYPE_P(zv) == IS_BOOL) { + if ((Z_TYPE_P(zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + REALLOC_BUF_IF_EXCEED(buf, offset, length, Z_STRLEN_P(zv)); + memcpy(offset, Z_STRVAL_P(zv), Z_STRLEN_P(zv)); + offset += Z_STRLEN_P(zv); + } else if (Z_TYPE_P(zv) == IS_BOOL) { if (Z_LVAL_P(zv)) { memcpy(offset, "true", 4); offset += 4; @@ -3487,6 +3490,9 @@ static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{ } else if (Z_TYPE_P(zv) == IS_ARRAY) { memcpy(offset, "Array", 5); offset += 5; + } else if ((Z_TYPE_P(zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT_AST) { + memcpy(offset, "<expression>", 12); + offset += 12; } else { zend_make_printable_zval(zv, &zv_copy, &use_copy); REALLOC_BUF_IF_EXCEED(buf, offset, length, Z_STRLEN(zv_copy)); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index bdf8b6e70f..6ada04e1cb 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -943,6 +943,26 @@ copy_value: } } +static void zval_deep_copy(zval **p) +{ + zval *value; + + ALLOC_ZVAL(value); + *value = **p; + if (Z_TYPE_P(value) == IS_ARRAY) { + HashTable *ht; + + ALLOC_HASHTABLE(ht); + zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(value)), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(ht, Z_ARRVAL_P(value), (copy_ctor_func_t) zval_deep_copy, NULL, sizeof(zval *)); + Z_ARRVAL_P(value) = ht; + } else { + zval_copy_ctor(value); + } + INIT_PZVAL(value); + *p = value; +} + /* Utility Functions for Extensions */ static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC) { @@ -1490,7 +1510,8 @@ ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_i } else { zval **return_value_ptr = &EX_TMP_VAR(execute_data_ptr, execute_data_ptr->opline->result.var)->var.ptr; execute_data_ptr->function_state.function->internal_function.handler( - execute_data_ptr->opline->extended_value, *return_value_ptr, return_value_ptr, + execute_data_ptr->opline->extended_value + execute_data_ptr->call->num_additional_args, + *return_value_ptr, return_value_ptr, execute_data_ptr->object, return_value_used TSRMLS_CC ); } diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 7cfd85d52a..8c2deb7fcc 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -449,8 +449,6 @@ ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ } /* }}} */ -#include "../TSRM/tsrm_strtok_r.h" - #define IS_VISITED_CONSTANT 0x80 #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 7d7c330710..2b4a8c9a16 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -125,6 +125,7 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished /* A fatal error / die occurred during the generator execution. Trying to clean * up the stack may not be safe in this case. */ if (CG(unclean_shutdown)) { + generator->execute_data = NULL; return; } diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 309631338a..a9fd3e9a43 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -487,6 +487,7 @@ ZEND_API void zend_hash_reindex(HashTable *ht, zend_bool only_integer_keys) { IS_CONSISTENT(ht); if (UNEXPECTED(ht->nNumOfElements == 0)) { + ht->nNextFreeElement = 0; return; } diff --git a/Zend/zend_highlight.c b/Zend/zend_highlight.c index 68f2b7b72d..31d99b7dfe 100644 --- a/Zend/zend_highlight.c +++ b/Zend/zend_highlight.c @@ -150,7 +150,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini case T_DOC_COMMENT: break; default: - efree(token.value.str.val); + str_efree(token.value.str.val); break; } } diff --git a/Zend/zend_indent.c b/Zend/zend_indent.c index 38ce669083..10f9af7823 100644 --- a/Zend/zend_indent.c +++ b/Zend/zend_indent.c @@ -138,7 +138,7 @@ dflt_printout: case T_WHITESPACE: break; default: - efree(token.value.str.val); + str_efree(token.value.str.val); break; } } diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index f022909bc3..ef21b47a41 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -963,7 +963,7 @@ ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ * } /* }}} */ -ZEND_API int pow_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) +ZEND_API int pow_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ { zval op1_copy, op2_copy; int converted = 0; @@ -1045,6 +1045,7 @@ ZEND_API int pow_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) } } } +/* }}} */ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index e6db12549a..8cbc356877 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2466,7 +2466,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); FREE_OP2(); FREE_OP1_IF_VAR(); @@ -3461,6 +3461,13 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) 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 if (Z_TYPE_P(assignment_value) == IS_ARRAY) { + HashTable *ht; + + ALLOC_HASHTABLE(ht); + zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(assignment_value)), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(ht, Z_ARRVAL_P(assignment_value), (copy_ctor_func_t) zval_deep_copy, NULL, sizeof(zval *)); + Z_ARRVAL_P(assignment_value) = ht; } else { zval_copy_ctor(assignment_value); } @@ -5439,6 +5446,7 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED) { USE_OPLINE zend_function *op_array; + int closure_is_static, closure_is_being_defined_inside_static_context; SAVE_OPLINE(); @@ -5447,7 +5455,13 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED) zend_error_noreturn(E_ERROR, "Base lambda function for closure not found"); } - zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC); + closure_is_static = op_array->common.fn_flags & ZEND_ACC_STATIC; + closure_is_being_defined_inside_static_context = EX(prev_execute_data) && EX(prev_execute_data)->function_state.function->common.fn_flags & ZEND_ACC_STATIC; + if (closure_is_static || closure_is_being_defined_inside_static_context) { + zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(called_scope), NULL TSRMLS_CC); + } else { + zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 399533de1a..c104199b10 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1624,6 +1624,13 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ 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 if (Z_TYPE_P(assignment_value) == IS_ARRAY) { + HashTable *ht; + + ALLOC_HASHTABLE(ht); + zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(assignment_value)), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(ht, Z_ARRVAL_P(assignment_value), (copy_ctor_func_t) zval_deep_copy, NULL, sizeof(zval *)); + Z_ARRVAL_P(assignment_value) = ht; } else { zval_copy_ctor(assignment_value); } @@ -6781,6 +6788,7 @@ static int ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER { USE_OPLINE zend_function *op_array; + int closure_is_static, closure_is_being_defined_inside_static_context; SAVE_OPLINE(); @@ -6789,7 +6797,13 @@ static int ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER zend_error_noreturn(E_ERROR, "Base lambda function for closure not found"); } - zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC); + closure_is_static = op_array->common.fn_flags & ZEND_ACC_STATIC; + closure_is_being_defined_inside_static_context = EX(prev_execute_data) && EX(prev_execute_data)->function_state.function->common.fn_flags & ZEND_ACC_STATIC; + if (closure_is_static || closure_is_being_defined_inside_static_context) { + zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(called_scope), NULL TSRMLS_CC); + } else { + zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -9309,7 +9323,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); if (EG(exception) != NULL) { @@ -10212,7 +10226,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); zval_dtor(free_op2.var); if (EG(exception) != NULL) { @@ -11116,7 +11130,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); zval_ptr_dtor_nogc(&free_op2.var); if (EG(exception) != NULL) { @@ -12600,7 +12614,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_ HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); if (EG(exception) != NULL) { @@ -15876,7 +15890,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); zval_ptr_dtor_nogc(&free_op1.var); @@ -18261,7 +18275,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); zval_dtor(free_op2.var); zval_ptr_dtor_nogc(&free_op1.var); @@ -20607,7 +20621,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); zval_ptr_dtor_nogc(&free_op2.var); zval_ptr_dtor_nogc(&free_op1.var); @@ -24103,7 +24117,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); zval_ptr_dtor_nogc(&free_op1.var); @@ -25784,7 +25798,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); if (EG(exception) != NULL) { @@ -27230,7 +27244,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); zval_dtor(free_op2.var); if (EG(exception) != NULL) { @@ -28582,7 +28596,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); zval_ptr_dtor_nogc(&free_op2.var); if (EG(exception) != NULL) { @@ -30362,7 +30376,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); if (EG(exception) != NULL) { @@ -33639,7 +33653,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); if (EG(exception) != NULL) { @@ -35789,7 +35803,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); zval_dtor(free_op2.var); if (EG(exception) != NULL) { @@ -37994,7 +38008,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); zval_ptr_dtor_nogc(&free_op2.var); if (EG(exception) != NULL) { @@ -41200,7 +41214,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H HANDLE_EXCEPTION(); } - zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", function_name_strval, zend_get_type_by_const(Z_TYPE_P(call->object))); if (EG(exception) != NULL) { diff --git a/acinclude.m4 b/acinclude.m4 index c25e59eef0..3ccc7b2620 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1711,7 +1711,7 @@ int main(int argc, char *argv[]) { FILE *fp; long position; - char *filename = "/tmp/phpglibccheck"; + char *filename = tmpnam(NULL); fp = fopen(filename, "w"); if (fp == NULL) { diff --git a/build/build.mk b/build/build.mk index ac5dadb313..2c189159a2 100644 --- a/build/build.mk +++ b/build/build.mk @@ -1,7 +1,7 @@ # +----------------------------------------------------------------------+ # | PHP Version 5 | # +----------------------------------------------------------------------+ -# | Copyright (c) 1997-2006 The PHP Group | +# | Copyright (c) 1997-2014 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 | @@ -14,8 +14,6 @@ # | Author: Sascha Schumann <sascha@schumann.cx> | # +----------------------------------------------------------------------+ # -# $Id$ -# # # Makefile to generate build tools # @@ -61,16 +59,6 @@ snapshot: md5sum $$distname.tar.bz2; \ bzip2 -t $$distname.tar.bz2 -cvsclean-work: - @for i in `find . -name .cvsignore`; do \ - (cd `dirname $$i` 2>/dev/null && rm -rf `cat .cvsignore | grep -v config.nice | sed 's/[[:space:]]/ /g'` *.o *.a *.lo *.la *.gcno *.gcda .libs || true); \ - done - -svnclean-work: - @for i in `find . -type d ! -path '*/.svn/*' | grep -v '.svn'`; do \ - (cd $$i 2>/dev/null && rm -rf `svn propget svn:ignore . | grep -v config.nice` *.o *.a *.lo *.la *.gcno *.gcda .libs || true); \ - done - gitclean-work: @if (test ! -f '.git/info/exclude' || grep -s "git-ls-files" .git/info/exclude); then \ (echo "Rebuild .git/info/exclude" && echo '*.o' > .git/info/exclude && git svn propget svn:ignore | grep -v config.nice >> .git/info/exclude); \ diff --git a/build/libtool.m4 b/build/libtool.m4 index 56658ccbb4..4d948b9078 100644 --- a/build/libtool.m4 +++ b/build/libtool.m4 @@ -1532,10 +1532,6 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd1*) - dynamic_linker=no - ;; - freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. @@ -5843,10 +5839,6 @@ _LT_EOF _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; - freebsd1*) - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c index cc845584f0..f310289d73 100644 --- a/ext/bz2/bz2.c +++ b/ext/bz2/bz2.c @@ -230,6 +230,9 @@ PHP_BZ2_API php_stream *_php_stream_bz2open(php_stream_wrapper *wrapper, #endif if (php_check_open_basedir(path_copy TSRMLS_CC)) { +#ifdef VIRTUAL_DIR + efree(path_copy); +#endif return NULL; } @@ -239,6 +242,9 @@ PHP_BZ2_API php_stream *_php_stream_bz2open(php_stream_wrapper *wrapper, if (opened_path && bz_file) { *opened_path = estrdup(path_copy); } +#ifdef VIRTUAL_DIR + efree(path_copy); +#endif path_copy = NULL; if (bz_file == NULL) { diff --git a/ext/com_dotnet/com_olechar.c b/ext/com_dotnet/com_olechar.c index a3e81978bd..bf42b4fffb 100644 --- a/ext/com_dotnet/com_olechar.c +++ b/ext/com_dotnet/com_olechar.c @@ -46,7 +46,13 @@ PHP_COM_DOTNET_API OLECHAR *php_com_string_to_olestring(char *string, uint strin if (string_len > 0) { olestring = (OLECHAR*)safe_emalloc(string_len, sizeof(OLECHAR), 0); + /* XXX if that's a real multibyte string, olestring is obviously allocated excessively. + This should be fixed by reallocating the olestring, but as emalloc is used, that doesn't + matter much. */ ok = MultiByteToWideChar(codepage, flags, string, string_len, olestring, string_len); + if (ok > 0 && ok < string_len) { + olestring[ok] = '\0'; + } } else { ok = FALSE; olestring = (OLECHAR*)emalloc(sizeof(OLECHAR)); diff --git a/ext/com_dotnet/com_variant.c b/ext/com_dotnet/com_variant.c index 3ddf016efb..3cc057127a 100644 --- a/ext/com_dotnet/com_variant.c +++ b/ext/com_dotnet/com_variant.c @@ -154,7 +154,11 @@ PHP_COM_DOTNET_API void php_com_variant_from_zval(VARIANT *v, zval *z, int codep case IS_STRING: V_VT(v) = VT_BSTR; olestring = php_com_string_to_olestring(Z_STRVAL_P(z), Z_STRLEN_P(z), codepage TSRMLS_CC); - V_BSTR(v) = SysAllocStringByteLen((char*)olestring, Z_STRLEN_P(z) * sizeof(OLECHAR)); + if (CP_UTF8 == codepage) { + V_BSTR(v) = SysAllocStringByteLen((char*)olestring, wcslen(olestring) * sizeof(OLECHAR)); + } else { + V_BSTR(v) = SysAllocStringByteLen((char*)olestring, Z_STRLEN_P(z) * sizeof(OLECHAR)); + } efree(olestring); break; diff --git a/ext/com_dotnet/tests/bug66431_0.phpt b/ext/com_dotnet/tests/bug66431_0.phpt new file mode 100644 index 0000000000..daac328538 --- /dev/null +++ b/ext/com_dotnet/tests/bug66431_0.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug #66431 Special Character via COM Interface (CP_UTF8), Scripting.FileSystemObject +--SKIPIF-- +<?php +if (!extension_loaded("com_dotnet")){ echo "skip COM/.Net support not present"; } +?> +--FILE-- +<?php + +$text= "Xin chà o cộng đồng PHP"; +$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.txt"); + +$fso = new COM("Scripting.FileSystemObject"); +$fh = $fso->OpenTextFile($fpath, 2, true); +$fh->Write($text); +$fh->Close(); + +$check_text = file_get_contents($fpath); + +$result = ($check_text == $text); + +var_dump($result); + +if (!$result) { + echo "Expected: '$check_text'\n"; + echo "Have: '$text'\n"; +} + +?> +===DONE=== +--CLEAN-- +<?php + +$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.txt"); + +if (file_exists($fpath)) { + unlink($fpath); +} +?> +--EXPECT-- +bool(true) +===DONE=== diff --git a/ext/com_dotnet/tests/bug66431_1.phpt b/ext/com_dotnet/tests/bug66431_1.phpt new file mode 100644 index 0000000000..d97011c2bb --- /dev/null +++ b/ext/com_dotnet/tests/bug66431_1.phpt @@ -0,0 +1,60 @@ +--TEST-- +Bug #66431 Special Character via COM Interface (CP_UTF8), Application.Word +--SKIPIF-- +<?php +if (!extension_loaded("com_dotnet")){ echo "skip COM/.Net support not present"; } + +try { + new COM("word.application", NULL, CP_UTF8); +} catch (Exception $e) { + die('skip ' . $e->getMessage(); +} + +?> +--FILE-- +<?php + +$text= "Xin chà o cộng đồng PHP"; +$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.docx"); + +com_load_typelib('Word.Application'); + +$Wrd = new COM("word.application", NULL, CP_UTF8); +$Wrd->Documents->Add(); +$Wrd->Selection->TypeText($text); +$Wrd->ActiveDocument->SaveAs($fpath); +$Wrd->ActiveDocument->Close(false); +$Wrd->Application->Quit(); +unset($Wrd); + +$Wrd = new COM("word.application", NULL, CP_UTF8); +$Wrd->Documents->Open($fpath, NULL, false); +$check_text = $Wrd->ActiveDocument->Range($Wrd->ActiveDocument->Sentences(1)->Start, $Wrd->ActiveDocument->Sentences(1)->End)->Text; +$Wrd->ActiveDocument->Close(false); +$Wrd->Application->Quit(); +unset($Wrd); + +/* trim the returned text as we'll get windows eol from a word doc. */ +$result = (trim($check_text) == $text); + +var_dump($result); + +if (!$result) { + echo "Expected: '$check_text'\n"; + echo "Have: '$text'\n"; +} + +?> +===DONE=== +--CLEAN-- +<?php + +$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.docx"); + +if (file_exists($fpath)) { + unlink($fpath); +} +?> +--EXPECT-- +bool(true) +===DONE=== diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 1995f23a08..f8b04295d7 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -2345,25 +2345,34 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue TSRMLS_DC) case CURLOPT_WRITEHEADER: { FILE *fp = NULL; int type; - void * what; + void *what = NULL; - what = zend_fetch_resource(zvalue TSRMLS_CC, -1, "File-Handle", &type, 1, php_file_le_stream(), php_file_le_pstream()); - if (!what) { - return FAILURE; - } + if (Z_TYPE_PP(zvalue) != IS_NULL) { + what = zend_fetch_resource(zvalue TSRMLS_CC, -1, "File-Handle", &type, 1, php_file_le_stream(), php_file_le_pstream()); + if (!what) { + return FAILURE; + } - if (FAILURE == php_stream_cast((php_stream *) what, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) { - return FAILURE; - } + if (FAILURE == php_stream_cast((php_stream *) what, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) { + return FAILURE; + } - if (!fp) { - return FAILURE; + if (!fp) { + return FAILURE; + } } error = CURLE_OK; switch (option) { case CURLOPT_FILE: - if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { + if (!what) { + if (ch->handlers->write->stream) { + Z_DELREF_P(ch->handlers->write->stream); + ch->handlers->write->stream = NULL; + } + ch->handlers->write->fp = NULL; + ch->handlers->write->method = PHP_CURL_STDOUT; + } else if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { if (ch->handlers->write->stream) { Z_DELREF_P(ch->handlers->write->stream); } @@ -2377,7 +2386,14 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue TSRMLS_DC) } break; case CURLOPT_WRITEHEADER: - if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { + if (!what) { + if (ch->handlers->write_header->stream) { + Z_DELREF_P(ch->handlers->write_header->stream); + ch->handlers->write_header->stream = NULL; + } + ch->handlers->write_header->fp = NULL; + ch->handlers->write_header->method = PHP_CURL_IGNORE; + } else if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { if (ch->handlers->write_header->stream) { Z_DELREF_P(ch->handlers->write_header->stream); } @@ -2391,16 +2407,30 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue TSRMLS_DC) } break; case CURLOPT_INFILE: - if (ch->handlers->read->stream) { - Z_DELREF_P(ch->handlers->read->stream); + if (!what) { + if (ch->handlers->read->stream) { + Z_DELREF_P(ch->handlers->read->stream); + ch->handlers->read->stream = NULL; + } + ch->handlers->read->fp = NULL; + ch->handlers->read->fd = 0; + } else { + if (ch->handlers->read->stream) { + Z_DELREF_P(ch->handlers->read->stream); + } + Z_ADDREF_PP(zvalue); + ch->handlers->read->fp = fp; + ch->handlers->read->fd = Z_LVAL_PP(zvalue); + ch->handlers->read->stream = *zvalue; } - Z_ADDREF_PP(zvalue); - ch->handlers->read->fp = fp; - ch->handlers->read->fd = Z_LVAL_PP(zvalue); - ch->handlers->read->stream = *zvalue; break; case CURLOPT_STDERR: - if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { + if (!what) { + if (ch->handlers->std_err) { + zval_ptr_dtor(&ch->handlers->std_err); + ch->handlers->std_err = NULL; + } + } else if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { if (ch->handlers->std_err) { zval_ptr_dtor(&ch->handlers->std_err); } diff --git a/ext/curl/tests/bug27023.phpt b/ext/curl/tests/bug27023.phpt index 62effec990..fce69f5708 100644 --- a/ext/curl/tests/bug27023.phpt +++ b/ext/curl/tests/bug27023.phpt @@ -4,18 +4,15 @@ Bug #27023 (CURLOPT_POSTFIELDS does not parse content types for files) error_reporting = E_ALL & ~E_DEPRECATED --SKIPIF-- <?php -if (!extension_loaded("curl")) { - exit("skip curl extension not loaded"); -} -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -} +include 'skipif.inc'; ?> --FILE-- <?php -$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); $ch = curl_init(); +curl_setopt($ch, CURLOPT_SAFE_UPLOAD, 0); curl_setopt($ch, CURLOPT_URL, "{$host}/get.php?test=file"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); diff --git a/ext/curl/tests/bug27023_2.phpt b/ext/curl/tests/bug27023_2.phpt new file mode 100644 index 0000000000..c878ebac31 --- /dev/null +++ b/ext/curl/tests/bug27023_2.phpt @@ -0,0 +1,44 @@ +--TEST-- +Bug #27023 (CURLOPT_POSTFIELDS does not parse content types for files) +--INI-- +error_reporting = E_ALL & ~E_DEPRECATED +--SKIPIF-- +<?php include 'skipif.inc'; ?> +--FILE-- +<?php + +include 'server.inc'; +$host = curl_cli_server_start(); +$ch = curl_init(); +curl_setopt($ch, CURLOPT_SAFE_UPLOAD, 1); +curl_setopt($ch, CURLOPT_URL, "{$host}/get.php?test=file"); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + +$file = curl_file_create(__DIR__ . '/curl_testdata1.txt'); +$params = array('file' => $file); +curl_setopt($ch, CURLOPT_POSTFIELDS, $params); +var_dump(curl_exec($ch)); + +$file = curl_file_create(__DIR__ . '/curl_testdata1.txt', "text/plain"); +$params = array('file' => $file); +curl_setopt($ch, CURLOPT_POSTFIELDS, $params); +var_dump(curl_exec($ch)); + +$file = curl_file_create(__DIR__ . '/curl_testdata1.txt', null, "foo.txt"); +$params = array('file' => $file); +curl_setopt($ch, CURLOPT_POSTFIELDS, $params); +var_dump(curl_exec($ch)); + +$file = curl_file_create(__DIR__ . '/curl_testdata1.txt', "text/plain", "foo.txt"); +$params = array('file' => $file); +curl_setopt($ch, CURLOPT_POSTFIELDS, $params); +var_dump(curl_exec($ch)); + + +curl_close($ch); +?> +--EXPECTF-- +string(%d) "curl_testdata1.txt|application/octet-stream" +string(%d) "curl_testdata1.txt|text/plain" +string(%d) "foo.txt|application/octet-stream" +string(%d) "foo.txt|text/plain" diff --git a/ext/curl/tests/bug45161.phpt b/ext/curl/tests/bug45161.phpt index 9fdc7a7e22..bfcd244004 100644 --- a/ext/curl/tests/bug45161.phpt +++ b/ext/curl/tests/bug45161.phpt @@ -8,9 +8,6 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { if (!extension_loaded("curl")) { exit("skip curl extension not loaded"); } -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -} $curl_version = curl_version(); if ($curl_version['version_number'] < 0x071100) { exit("skip: test works only with curl >= 7.17.0"); diff --git a/ext/curl/tests/bug46711.phpt b/ext/curl/tests/bug46711.phpt index 8eef5562fe..3149c45d7e 100644 --- a/ext/curl/tests/bug46711.phpt +++ b/ext/curl/tests/bug46711.phpt @@ -5,9 +5,6 @@ Bug #46711 (lost memory when foreach is used for values passed to curl_setopt()) if (!extension_loaded("curl")) { exit("skip curl extension not loaded"); } -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -} ?> --FILE-- <?php diff --git a/ext/curl/tests/bug48203.phpt b/ext/curl/tests/bug48203.phpt index d8f4d2269f..aae7fc51a4 100644 --- a/ext/curl/tests/bug48203.phpt +++ b/ext/curl/tests/bug48203.phpt @@ -1,24 +1,17 @@ --TEST-- Bug #48203 (Crash when CURLOPT_STDERR is set to regular file) --SKIPIF-- -<?php -if (!extension_loaded("curl")) { - exit("skip curl extension not loaded"); -} -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -} -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - +include 'server.inc'; $fp = fopen(dirname(__FILE__) . '/bug48203.tmp', 'w'); $ch = curl_init(); curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_STDERR, $fp); -curl_setopt($ch, CURLOPT_URL, getenv('PHP_CURL_HTTP_REMOTE_SERVER')); +curl_setopt($ch, CURLOPT_URL, curl_cli_server_start()); fclose($fp); // <-- premature close of $fp caused a crash! diff --git a/ext/curl/tests/bug48203_multi.phpt b/ext/curl/tests/bug48203_multi.phpt index 501b77843e..e28c990e93 100644 --- a/ext/curl/tests/bug48203_multi.phpt +++ b/ext/curl/tests/bug48203_multi.phpt @@ -2,16 +2,11 @@ Variation of bug #48203 with curl_multi_exec (Crash when file pointers passed to curl are closed before calling curl_multi_exec) --SKIPIF-- <?php -if (!extension_loaded("curl")) { - exit("skip curl extension not loaded"); -} -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -} +include 'skipif.inc'; ?> --FILE-- <?php - +include 'server.inc'; function checkForClosedFilePointer($curl_option, $description) { $fp = fopen(dirname(__FILE__) . '/bug48203.tmp', 'w'); @@ -21,7 +16,7 @@ function checkForClosedFilePointer($curl_option, $description) { $options = array( CURLOPT_RETURNTRANSFER => 1, $curl_option => $fp, - CURLOPT_URL => getenv("PHP_CURL_HTTP_REMOTE_SERVER") + CURLOPT_URL => curl_cli_server_start() ); // we also need to set CURLOPT_VERBOSE to test CURLOPT_STDERR properly diff --git a/ext/curl/tests/bug48207.phpt b/ext/curl/tests/bug48207.phpt index 6ac16f5ea8..a3cd81544b 100644 --- a/ext/curl/tests/bug48207.phpt +++ b/ext/curl/tests/bug48207.phpt @@ -4,7 +4,7 @@ Test curl_setopt() CURLOPT_FILE readonly file handle Mark van der Velden #testfest Utrecht 2009 --SKIPIF-- -<?php if (!extension_loaded("curl")) print "skip"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* @@ -14,7 +14,8 @@ Mark van der Velden */ // Figure out what handler to use -$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +include 'server.inc'; +$host = curl_cli_server_start(); if(!empty($host)) { // Use the set Environment variable diff --git a/ext/curl/tests/bug54798.phpt b/ext/curl/tests/bug54798.phpt index f633a8ab2a..4a9b999940 100644 --- a/ext/curl/tests/bug54798.phpt +++ b/ext/curl/tests/bug54798.phpt @@ -2,12 +2,7 @@ Bug #54798 (Segfault when CURLOPT_STDERR file pointer is closed before calling curl_exec) --SKIPIF-- <?php -if (!extension_loaded("curl")) { - exit("skip curl extension not loaded"); -} -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -} +include 'skipif.inc'; ?> --FILE-- <?php @@ -47,25 +42,20 @@ $options_to_check = array( "CURLOPT_INFILE" ); -$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +include 'server.inc'; +$host = curl_cli_server_start(); foreach($options_to_check as $option) { checkForClosedFilePointer($host, constant($option), $option); } ?> +===DONE=== --CLEAN-- <?php @unlink(dirname(__FILE__) . '/bug54798.tmp'); ?> --EXPECTF-- -Warning: curl_exec(): CURLOPT_STDERR resource has gone away, resetting to stderr in %sbug54798.php on line %d -* About to connect() %a -* Closing connection %d -Ok for CURLOPT_STDERR - -Warning: curl_exec(): CURLOPT_WRITEHEADER resource has gone away, resetting to default in %sbug54798.php on line 24 -Ok for CURLOPT_WRITEHEADER - -Warning: curl_exec(): CURLOPT_FILE resource has gone away, resetting to default in %sbug54798.php on line 24 +%a +%aOk for CURLOPT_STDERR +%aOk for CURLOPT_WRITEHEADER %aOk for CURLOPT_FILE - -Warning: curl_exec(): CURLOPT_INFILE resource has gone away, resetting to default in %sbug54798.php on line %d -Ok for CURLOPT_INFILE +%aOk for CURLOPT_INFILE +===DONE=== diff --git a/ext/curl/tests/bug54995.phpt b/ext/curl/tests/bug54995.phpt index 0f3f50f344..4af59948be 100644 --- a/ext/curl/tests/bug54995.phpt +++ b/ext/curl/tests/bug54995.phpt @@ -2,20 +2,16 @@ Bug #54995 (Missing CURLINFO_RESPONSE_CODE support) --SKIPIF-- <?php -if (!extension_loaded("curl")) { - exit("skip curl extension not loaded"); -} +include 'skipif.inc'; + if ($curl_version['version_number'] > 0x070a08) { exit("skip: tests works a versions of curl >= 7.10.8"); } -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -} ?> --FILE-- <?php - -$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +include 'server.inc'; +$host = curl_cli_server_start(); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "{$host}/get.php"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); diff --git a/ext/curl/tests/bug55767.phpt b/ext/curl/tests/bug55767.phpt index 321f67ba60..161ced0bf1 100644 --- a/ext/curl/tests/bug55767.phpt +++ b/ext/curl/tests/bug55767.phpt @@ -2,8 +2,7 @@ Test curl_opt() function with POST params from array with a numeric key --SKIPIF-- <?php -if (!extension_loaded("curl")) exit("skip curl extension not loaded"); -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +include 'skipinf.inc'; ?> --FILE-- <?php @@ -13,7 +12,8 @@ if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_R * Alias to functions: */ - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo '*** Testing curl sending through GET an POST ***' . "\n"; diff --git a/ext/curl/tests/bug64267.phpt b/ext/curl/tests/bug64267.phpt new file mode 100644 index 0000000000..1b115588ff --- /dev/null +++ b/ext/curl/tests/bug64267.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #64267 (CURLOPT_INFILE doesn't allow reset) +--SKIPIF-- +<?php +extension_loaded("curl") or die("skip need ext/curl"); +?> +--FILE-- +<?php + +echo "TEST\n"; + +$c = curl_init("http://google.com"); +$f = fopen(__FILE__,"r"); +var_dump(curl_setopt_array($c, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_UPLOAD => true, + CURLOPT_INFILE => $f, + CURLOPT_INFILESIZE => filesize(__FILE__) +])); +fclose($f); +var_dump(curl_setopt_array($c, [ + CURLOPT_UPLOAD => false, + CURLOPT_INFILE => null, + CURLOPT_INFILESIZE => 0, +])); +curl_exec($c); +var_dump(curl_getinfo($c, CURLINFO_RESPONSE_CODE)); +?> +===DONE=== +--EXPECTF-- +TEST +bool(true) +bool(true) +int(30%d) +===DONE=== diff --git a/ext/curl/tests/bug66109.phpt b/ext/curl/tests/bug66109.phpt index aacfba438a..5a18e97294 100644 --- a/ext/curl/tests/bug66109.phpt +++ b/ext/curl/tests/bug66109.phpt @@ -1,18 +1,11 @@ --TEST-- Bug #66109 (Option CURLOPT_CUSTOMREQUEST can't be reset to default.) --SKIPIF-- -<?php -if (!extension_loaded("curl")) { - exit("skip curl extension not loaded"); -} -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -} -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - -$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +include 'server.inc'; +$host = curl_cli_server_start(); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "{$host}/get.php?test=method"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); diff --git a/ext/curl/tests/curl_CURLOPT_READDATA.phpt b/ext/curl/tests/curl_CURLOPT_READDATA.phpt index ea63d445ac..25bd0e9b49 100644 --- a/ext/curl/tests/curl_CURLOPT_READDATA.phpt +++ b/ext/curl/tests/curl_CURLOPT_READDATA.phpt @@ -4,12 +4,14 @@ Test CURLOPT_READDATA without a callback function Mattijs Hoitink mattijshoitink@gmail.com #Testfest Utrecht 2009 --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php +include 'server.inc'; +$host = curl_cli_server_start(); // The URL to POST to -$url = getenv('PHP_CURL_HTTP_REMOTE_SERVER') . '/get.php?test=post'; +$url = $host . '/get.php?test=post'; // Create a temporary file to read the data from $tempname = tempnam(sys_get_temp_dir(), 'CURL_DATA'); diff --git a/ext/curl/tests/curl_basic_001.phpt b/ext/curl/tests/curl_basic_001.phpt index fa362b33ce..4921b69bdd 100644 --- a/ext/curl/tests/curl_basic_001.phpt +++ b/ext/curl/tests/curl_basic_001.phpt @@ -4,10 +4,7 @@ Test curl_exec() function with basic functionality Sebastian Deutsch <sebastian.deutsch@9elements.com> TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> --SKIPIF-- -<?php -if (!extension_loaded("curl")) exit("skip curl extension not loaded"); -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* Prototype : bool curl_exec(resource ch) @@ -15,8 +12,8 @@ if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_R * Source code: ext/curl/interface.c * Alias to functions: */ - - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo "*** Testing curl_exec() : basic functionality ***\n"; diff --git a/ext/curl/tests/curl_basic_002.phpt b/ext/curl/tests/curl_basic_002.phpt index e46f323b5a..69aef4b825 100644 --- a/ext/curl/tests/curl_basic_002.phpt +++ b/ext/curl/tests/curl_basic_002.phpt @@ -4,10 +4,7 @@ Test curl_opt() function with CURLOPT_RETURNTRANSFER parameter set to 1 Sebastian Deutsch <sebastian.deutsch@9elements.com> TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> --SKIPIF-- -<?php -if (!extension_loaded("curl")) exit("skip curl extension not loaded"); -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* Prototype : bool curl_setopt(resource ch, int option, mixed value) @@ -16,7 +13,8 @@ if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_R * Alias to functions: */ - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo '*** Testing curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); ***' . "\n"; diff --git a/ext/curl/tests/curl_basic_003.phpt b/ext/curl/tests/curl_basic_003.phpt index eb2aecdd8f..9c5967db8f 100644 --- a/ext/curl/tests/curl_basic_003.phpt +++ b/ext/curl/tests/curl_basic_003.phpt @@ -4,10 +4,7 @@ Test curl_opt() function with POST parameters Sebastian Deutsch <sebastian.deutsch@9elements.com> TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> --SKIPIF-- -<?php -if (!extension_loaded("curl")) exit("skip curl extension not loaded"); -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* Prototype : bool curl_setopt(resource ch, int option, mixed value) @@ -16,7 +13,8 @@ if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_R * Alias to functions: */ - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo '*** Testing curl sending through GET an POST ***' . "\n"; diff --git a/ext/curl/tests/curl_basic_004.phpt b/ext/curl/tests/curl_basic_004.phpt index ea2eeca87c..08dc7a1005 100644 --- a/ext/curl/tests/curl_basic_004.phpt +++ b/ext/curl/tests/curl_basic_004.phpt @@ -4,10 +4,7 @@ Test curl_opt() function with setting referer Sebastian Deutsch <sebastian.deutsch@9elements.com> TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> --SKIPIF-- -<?php -if (!extension_loaded("curl")) exit("skip curl extension not loaded"); -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* Prototype : bool curl_setopt(resource ch, int option, mixed value) @@ -16,7 +13,8 @@ if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_R * Alias to functions: */ - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo '*** Testing curl setting referer ***' . "\n"; diff --git a/ext/curl/tests/curl_basic_005.phpt b/ext/curl/tests/curl_basic_005.phpt index 9285c108e2..200db765dc 100644 --- a/ext/curl/tests/curl_basic_005.phpt +++ b/ext/curl/tests/curl_basic_005.phpt @@ -4,10 +4,7 @@ Test curl_opt() function with user agent Sebastian Deutsch <sebastian.deutsch@9elements.com> TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> --SKIPIF-- -<?php -if (!extension_loaded("curl")) exit("skip curl extension not loaded"); -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* Prototype : bool curl_setopt(resource ch, int option, mixed value) @@ -16,7 +13,8 @@ if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_R * Alias to functions: */ - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo '*** Testing curl with user agent ***' . "\n"; diff --git a/ext/curl/tests/curl_basic_006.phpt b/ext/curl/tests/curl_basic_006.phpt index 5f1a4f4839..e48a5ba70d 100644 --- a/ext/curl/tests/curl_basic_006.phpt +++ b/ext/curl/tests/curl_basic_006.phpt @@ -4,10 +4,7 @@ Test curl_opt() function with CURLOPT_WRITEFUNCTION parameter set to a closure ? TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> --SKIPIF-- -<?php -if (!extension_loaded("curl")) exit("skip curl extension not loaded"); -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* Prototype : bool curl_setopt(resource ch, int option, mixed value) @@ -16,23 +13,26 @@ if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_R * Alias to functions: */ - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo '*** Testing curl_setopt($ch, CURLOPT_WRITEFUNCTION, <closure>); ***' . "\n"; $url = "{$host}/get.php?test=get"; $ch = curl_init(); - + $alldata = ''; ob_start(); // start output buffering curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $data) { - echo 'Data: '.$data; + $GLOBALS['alldata'] .= $data; return strlen ($data); }); - + curl_exec($ch); curl_close($ch); + ob_end_flush(); + echo "Data: $alldata"; ?> ===DONE=== --EXPECTF-- diff --git a/ext/curl/tests/curl_basic_008.phpt b/ext/curl/tests/curl_basic_008.phpt index 29e3343707..4f0a29d7ff 100644 --- a/ext/curl/tests/curl_basic_008.phpt +++ b/ext/curl/tests/curl_basic_008.phpt @@ -25,5 +25,5 @@ curl_close($ch); ?> --EXPECTF-- -%unicode|string%(%d) "%r(Couldn't resolve host|Could not resolve host:)%r %Swww.%s" +%s resolve%s int(6) diff --git a/ext/curl/tests/curl_basic_010.phpt b/ext/curl/tests/curl_basic_010.phpt index 0fc2fe6656..72a591ff16 100644 --- a/ext/curl/tests/curl_basic_010.phpt +++ b/ext/curl/tests/curl_basic_010.phpt @@ -26,5 +26,5 @@ curl_close($ch); ?> --EXPECTF-- -%unicode|string%(%d) "%r(Couldn't resolve proxy|Could not resolve proxy:|Could not resolve host:)%r %s" +%unicode|string%(%d) "%r(Couldn't resolve proxy|Could not resolve proxy:|Could not resolve host:|Could not resolve:)%r %s" int(5) diff --git a/ext/curl/tests/curl_basic_011.phpt b/ext/curl/tests/curl_basic_011.phpt index 10c90b123a..4e33082409 100644 --- a/ext/curl/tests/curl_basic_011.phpt +++ b/ext/curl/tests/curl_basic_011.phpt @@ -3,7 +3,7 @@ Test curl_opt() function with COOKIE --CREDITS-- TestFest 2009 - AFUP - Xavier Gorse <xgorse@elao.com> --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv(b'PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* Prototype : bool curl_setopt(resource ch, int option, mixed value) @@ -12,7 +12,8 @@ TestFest 2009 - AFUP - Xavier Gorse <xgorse@elao.com> * Alias to functions: */ - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo '*** Testing curl with cookie ***' . "\n"; diff --git a/ext/curl/tests/curl_basic_012.phpt b/ext/curl/tests/curl_basic_012.phpt index e4706fad46..f136880dff 100644 --- a/ext/curl/tests/curl_basic_012.phpt +++ b/ext/curl/tests/curl_basic_012.phpt @@ -3,7 +3,7 @@ Test curl_opt() function with CURLOPT_HTTP_VERSION/CURL_HTTP_VERSION_1_0 --CREDITS-- TestFest 2009 - AFUP - Xavier Gorse <xgorse@elao.com> --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv(b'PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* Prototype : bool curl_setopt(resource ch, int option, mixed value) @@ -12,7 +12,8 @@ TestFest 2009 - AFUP - Xavier Gorse <xgorse@elao.com> * Alias to functions: */ - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo '*** Testing curl with HTTP/1.0 ***' . "\n"; diff --git a/ext/curl/tests/curl_basic_013.phpt b/ext/curl/tests/curl_basic_013.phpt index c49d187be3..6d09517e8d 100644 --- a/ext/curl/tests/curl_basic_013.phpt +++ b/ext/curl/tests/curl_basic_013.phpt @@ -3,7 +3,7 @@ Test curl_opt() function with CURLOPT_HTTP_VERSION/CURL_HTTP_VERSION_1_1 --CREDITS-- TestFest 2009 - AFUP - Xavier Gorse <xgorse@elao.com> --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv(b'PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* Prototype : bool curl_setopt(resource ch, int option, mixed value) @@ -12,7 +12,8 @@ TestFest 2009 - AFUP - Xavier Gorse <xgorse@elao.com> * Alias to functions: */ - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo '*** Testing curl with HTTP/1.1 ***' . "\n"; diff --git a/ext/curl/tests/curl_basic_017.phpt b/ext/curl/tests/curl_basic_017.phpt index 09247b2c69..dc0bee926b 100644 --- a/ext/curl/tests/curl_basic_017.phpt +++ b/ext/curl/tests/curl_basic_017.phpt @@ -3,7 +3,7 @@ Test curl_multi_exec() function with basic functionality --CREDITS-- TestFest 2009 - AFUP - Thomas Rabaix <thomas.rabaix@gmail.com> --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* Prototype : bool curl_multi_exec(resource ch) @@ -12,7 +12,8 @@ TestFest 2009 - AFUP - Thomas Rabaix <thomas.rabaix@gmail.com> * Alias to functions: */ - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo "*** Testing curl_exec() : basic functionality ***\n"; diff --git a/ext/curl/tests/curl_basic_018.phpt b/ext/curl/tests/curl_basic_018.phpt index 7cffb89f01..359421fc0a 100644 --- a/ext/curl/tests/curl_basic_018.phpt +++ b/ext/curl/tests/curl_basic_018.phpt @@ -3,7 +3,7 @@ Test curl_setopt() with curl_multi function with basic functionality --CREDITS-- TestFest 2009 - AFUP - Thomas Rabaix <thomas.rabaix@gmail.com> --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* Prototype : bool curl_setopt(resource ch, int option, mixed value) @@ -12,7 +12,8 @@ TestFest 2009 - AFUP - Thomas Rabaix <thomas.rabaix@gmail.com> * Alias to functions: */ - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); // start testing echo "*** Testing curl_exec() : basic functionality ***\n"; diff --git a/ext/curl/tests/curl_basic_019.phpt b/ext/curl/tests/curl_basic_019.phpt index ab605a8c7d..2c58500ef7 100644 --- a/ext/curl/tests/curl_basic_019.phpt +++ b/ext/curl/tests/curl_basic_019.phpt @@ -3,22 +3,19 @@ Test curl_getinfo() function with CURLINFO_EFFECTIVE_URL parameter --CREDITS-- Jean-Marc Fontaine <jmf@durcommefaire.net> --SKIPIF-- -<?php -if (!extension_loaded("curl")) exit("skip curl extension not loaded"); -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); - $url = "{$host}/get.php?test="; + $url = "http://{$host}/get.php?test="; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_exec($ch); $info = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); var_dump($url == $info); - curl_close($ch); ?> ===DONE=== diff --git a/ext/curl/tests/curl_basic_020.phpt b/ext/curl/tests/curl_basic_020.phpt index d622053506..1227ad3261 100644 --- a/ext/curl/tests/curl_basic_020.phpt +++ b/ext/curl/tests/curl_basic_020.phpt @@ -3,13 +3,11 @@ Test curl_getinfo() function with CURLINFO_HTTP_CODE parameter --CREDITS-- Jean-Marc Fontaine <jmf@durcommefaire.net> --SKIPIF-- -<?php -if (!extension_loaded("curl")) exit("skip curl extension not loaded"); -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); $url = "{$host}/get.php?test="; $ch = curl_init(); diff --git a/ext/curl/tests/curl_basic_021.phpt b/ext/curl/tests/curl_basic_021.phpt index 3b4798d515..d9f5a90bef 100644 --- a/ext/curl/tests/curl_basic_021.phpt +++ b/ext/curl/tests/curl_basic_021.phpt @@ -3,13 +3,11 @@ Test curl_getinfo() function with CURLINFO_CONTENT_TYPE parameter --CREDITS-- Jean-Marc Fontaine <jmf@durcommefaire.net> --SKIPIF-- -<?php -if (!extension_loaded("curl")) exit("skip curl extension not loaded"); -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); $url = "{$host}/get.php?test=contenttype"; $ch = curl_init(); diff --git a/ext/curl/tests/curl_copy_handle_basic_001.phpt b/ext/curl/tests/curl_copy_handle_basic_001.phpt index f1b4db3ce5..aafa41ee2e 100644 --- a/ext/curl/tests/curl_copy_handle_basic_001.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_001.phpt @@ -4,11 +4,12 @@ Test curl_copy_handle() with simple get Rick Buitenman <rick@meritos.nl> #testfest Utrecht 2009 --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); echo '*** Testing curl copy handle with simple GET ***' . "\n"; diff --git a/ext/curl/tests/curl_copy_handle_basic_002.phpt b/ext/curl/tests/curl_copy_handle_basic_002.phpt index 9ab33635fb..6e8214ad2b 100644 --- a/ext/curl/tests/curl_copy_handle_basic_002.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_002.phpt @@ -4,10 +4,11 @@ Test curl_copy_handle() with simple POST Rick Buitenman <rick@meritos.nl> #testfest Utrecht 2009 --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); echo '*** Testing curl copy handle with simple POST ***' . "\n"; diff --git a/ext/curl/tests/curl_copy_handle_basic_004.phpt b/ext/curl/tests/curl_copy_handle_basic_004.phpt index 9b794e91b4..c690180a55 100644 --- a/ext/curl/tests/curl_copy_handle_basic_004.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_004.phpt @@ -4,11 +4,12 @@ Test curl_copy_handle() after exec() Rick Buitenman <rick@meritos.nl> #testfest Utrecht 2009 --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); echo '*** Test curl_copy_handle() after exec() ***' . "\n"; diff --git a/ext/curl/tests/curl_copy_handle_basic_005.phpt b/ext/curl/tests/curl_copy_handle_basic_005.phpt index aa9e2fa998..e92603324e 100644 --- a/ext/curl/tests/curl_copy_handle_basic_005.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_005.phpt @@ -4,11 +4,12 @@ Test curl_copy_handle() after exec() with POST Rick Buitenman <rick@meritos.nl> #testfest Utrecht 2009 --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); echo '*** Test curl_copy_handle() after exec() with POST ***' . "\n"; diff --git a/ext/curl/tests/curl_copy_handle_basic_006.phpt b/ext/curl/tests/curl_copy_handle_basic_006.phpt index defc0f232a..0a5c2a25e6 100644 --- a/ext/curl/tests/curl_copy_handle_basic_006.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_006.phpt @@ -4,11 +4,12 @@ Test curl_copy_handle() with User Agent Rick Buitenman <rick@meritos.nl> #testfest Utrecht 2009 --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); echo '*** Testing curl copy handle with User Agent ***' . "\n"; diff --git a/ext/curl/tests/curl_copy_handle_basic_007.phpt b/ext/curl/tests/curl_copy_handle_basic_007.phpt index aa7306c1c9..6334d2a4b8 100644 --- a/ext/curl/tests/curl_copy_handle_basic_007.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_007.phpt @@ -1,10 +1,11 @@ --TEST-- Test curl_copy_handle() with simple POST --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); echo '*** Testing curl copy handle with simple POST using array as arguments ***' . "\n"; diff --git a/ext/curl/tests/curl_copy_handle_basic_008.phpt b/ext/curl/tests/curl_copy_handle_basic_008.phpt index 692c2df192..cdb7de374d 100644 --- a/ext/curl/tests/curl_copy_handle_basic_008.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_008.phpt @@ -1,10 +1,11 @@ --TEST-- Test curl_copy_handle() with CURLOPT_PROGRESSFUNCTION --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); $url = "{$host}/get.php"; $ch = curl_init($url); diff --git a/ext/curl/tests/curl_file_deleted_before_curl_close.phpt b/ext/curl/tests/curl_file_deleted_before_curl_close.phpt index 3a4d949e75..5e806add08 100644 --- a/ext/curl/tests/curl_file_deleted_before_curl_close.phpt +++ b/ext/curl/tests/curl_file_deleted_before_curl_close.phpt @@ -3,11 +3,13 @@ Memory corruption error if fp of just created file is closed before curl_close. --CREDITS-- Alexey Shein <confik@gmail.com> --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php -$ch = curl_init(getenv('PHP_CURL_HTTP_REMOTE_SERVER')); +include 'server.inc'; +$host = curl_cli_server_start(); +$ch = curl_init($host); $temp_file = dirname(__FILE__) . '/curl_file_deleted_before_curl_close.tmp'; if (file_exists($temp_file)) { diff --git a/ext/curl/tests/curl_file_upload.phpt b/ext/curl/tests/curl_file_upload.phpt index d3168e578a..3a5a78fde3 100644 --- a/ext/curl/tests/curl_file_upload.phpt +++ b/ext/curl/tests/curl_file_upload.phpt @@ -1,14 +1,8 @@ --TEST-- CURL file uploading +--INI-- --SKIPIF-- -<?php -if (!extension_loaded("curl")) { - exit("skip curl extension not loaded"); -} -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -} -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php @@ -25,7 +19,8 @@ function testcurl($ch, $name, $mime = '', $postname = '') var_dump(curl_exec($ch)); } -$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +include 'server.inc'; +$host = curl_cli_server_start(); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "{$host}/get.php?test=file"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); @@ -48,6 +43,7 @@ var_dump($file->getPostFilename()); curl_setopt($ch, CURLOPT_POSTFIELDS, array("file" => $file)); var_dump(curl_exec($ch)); +curl_setopt($ch, CURLOPT_SAFE_UPLOAD, 0); $params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt'); curl_setopt($ch, CURLOPT_POSTFIELDS, $params); var_dump(curl_exec($ch)); diff --git a/ext/curl/tests/curl_multi_getcontent_basic3.phpt b/ext/curl/tests/curl_multi_getcontent_basic3.phpt index ac2a371724..190fe9d9c0 100644 --- a/ext/curl/tests/curl_multi_getcontent_basic3.phpt +++ b/ext/curl/tests/curl_multi_getcontent_basic3.phpt @@ -4,12 +4,7 @@ Curl_multi_getcontent() basic test with different sources (local file/http) Rein Velt (rein@velt.org) #TestFest Utrecht 20090509 --SKIPIF-- -<?php -if (!extension_loaded('curl')) print 'skip need ext/curl'; -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -} -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php //CURL_MULTI_GETCONTENT TEST @@ -19,7 +14,8 @@ if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { $ch2=curl_init(); //SET URL AND OTHER OPTIONS - $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + include 'server.inc'; + $host = curl_cli_server_start(); curl_setopt($ch1, CURLOPT_URL, "{$host}/get.php?test=getpost&get_param=Hello%20World"); curl_setopt($ch2, CURLOPT_URL, "file://".dirname(__FILE__). DIRECTORY_SEPARATOR . "curl_testdata2.txt"); curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true); diff --git a/ext/curl/tests/curl_reset.phpt b/ext/curl/tests/curl_reset.phpt index c78a8e0953..3572e69543 100644 --- a/ext/curl/tests/curl_reset.phpt +++ b/ext/curl/tests/curl_reset.phpt @@ -36,5 +36,8 @@ unlink($test_file); unlink($log_file); ?> + +===DONE=== --EXPECT-- testtest +===DONE=== diff --git a/ext/curl/tests/curl_setopt_array_basic.phpt b/ext/curl/tests/curl_setopt_array_basic.phpt index 427de7fc75..d858241b78 100644 --- a/ext/curl/tests/curl_setopt_array_basic.phpt +++ b/ext/curl/tests/curl_setopt_array_basic.phpt @@ -4,7 +4,7 @@ curl_setopt_array() function - tests setting multiple cURL options with curl_set Mattijs Hoitink mattijshoitink@gmail.com #Testfest Utrecht 2009 --SKIPIF-- -<?php if (!extension_loaded("curl")) print "skip"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php /* @@ -15,7 +15,8 @@ Mattijs Hoitink mattijshoitink@gmail.com */ // Figure out what handler to use -$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +include 'server.inc'; +$host = curl_cli_server_start(); if (!empty($host)) { // Use the set Environment variable $url = "{$host}/get.php?test=get"; diff --git a/ext/curl/tests/curl_setopt_basic002.phpt b/ext/curl/tests/curl_setopt_basic002.phpt index 074158a4b3..7a11493ed2 100644 --- a/ext/curl/tests/curl_setopt_basic002.phpt +++ b/ext/curl/tests/curl_setopt_basic002.phpt @@ -4,11 +4,12 @@ curl_setopt basic tests with CURLOPT_STDERR. Paul Sohier #phptestfest utrecht --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php -$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +include 'server.inc'; +$host = curl_cli_server_start(); // start testing echo "*** Testing curl_setopt with CURLOPT_STDERR\n"; diff --git a/ext/curl/tests/curl_setopt_basic003.phpt b/ext/curl/tests/curl_setopt_basic003.phpt index aa225c6e33..246b83b418 100644 --- a/ext/curl/tests/curl_setopt_basic003.phpt +++ b/ext/curl/tests/curl_setopt_basic003.phpt @@ -4,11 +4,12 @@ curl_setopt() call with CURLOPT_HTTPHEADER Paul Sohier #phptestfest utrecht --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php -$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +include 'server.inc'; +$host = curl_cli_server_start(); // start testing echo "*** curl_setopt() call with CURLOPT_HTTPHEADER\n"; diff --git a/ext/curl/tests/curl_setopt_basic004.phpt b/ext/curl/tests/curl_setopt_basic004.phpt index 97b4115e3c..ee0b4921d5 100644 --- a/ext/curl/tests/curl_setopt_basic004.phpt +++ b/ext/curl/tests/curl_setopt_basic004.phpt @@ -4,11 +4,12 @@ curl_setopt() call with CURLOPT_RETURNTRANSFER Paul Sohier #phptestfest utrecht --SKIPIF-- -<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +<?php include 'skipif.inc'; ?> --FILE-- <?php -$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +include 'server.inc'; +$host = curl_cli_server_start(); // start testing echo "*** curl_setopt() call with CURLOPT_RETURNTRANSFER set to 1\n"; diff --git a/ext/curl/tests/curl_version_error.phpt b/ext/curl/tests/curl_version_error.phpt index fb4793af16..a9b80c55be 100644 --- a/ext/curl/tests/curl_version_error.phpt +++ b/ext/curl/tests/curl_version_error.phpt @@ -1,14 +1,7 @@ --TEST--
Test curl_version() function : error conditions
--SKIPIF--
-<?php
-if (!extension_loaded("curl")) {
- die('skip - curl extension not available in this build');
-}
-if (!getenv('PHP_CURL_HTTP_REMOTE_SERVER')) {
- echo "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable";
-}
-?>
+<?php if (!extension_loaded("curl")) exit("skip curl extension not loaded"); ?>
--FILE--
<?php
diff --git a/ext/curl/tests/curl_version_variation1.phpt b/ext/curl/tests/curl_version_variation1.phpt index cd912c4803..927b4ac317 100644 --- a/ext/curl/tests/curl_version_variation1.phpt +++ b/ext/curl/tests/curl_version_variation1.phpt @@ -1,14 +1,7 @@ --TEST--
Test curl_version() function : usage variations - test values for $ascii argument
--SKIPIF--
-<?php
-if (!extension_loaded("curl")) {
- echo "skip - curl extension not available in this build";
-}
-if (!getenv('PHP_CURL_HTTP_REMOTE_SERVER')) {
- echo "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable";
-}
-?>
+<?php if (!extension_loaded("curl")) exit("skip curl extension not loaded"); ?>
--FILE--
<?php
diff --git a/ext/curl/tests/curl_writeheader_callback.phpt b/ext/curl/tests/curl_writeheader_callback.phpt index fa27363a41..46e0cc18ba 100644 --- a/ext/curl/tests/curl_writeheader_callback.phpt +++ b/ext/curl/tests/curl_writeheader_callback.phpt @@ -4,16 +4,9 @@ Test curl option CURLOPT_HEADERFUNCTION Mathieu Kooiman <mathieuk@gmail.com> Dutch UG, TestFest 2009, Utrecht --DESCRIPTION-- -Hit the host identified by PHP_CURL_HTTP_REMOTE_SERVER and determine that the headers are sent to the callback specified for CURLOPT_HEADERFUNCTION. Different test servers specified for PHP_CURL_HTTP_REMOTE_SERVER might return different sets of headers. Just test for HTTP/1.1 200 OK. +Hit the host and determine that the headers are sent to the callback specified for CURLOPT_HEADERFUNCTION. Different test servers might return different sets of headers. Just test for HTTP/1.1 200 OK. --SKIPIF-- -<?php -if (!extension_loaded("curl")) { - echo "skip - curl extension not available in this build"; -} -if (!getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - echo "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; -} -?> +<?php include 'skipif.inc'; ?> --FILE-- <?php @@ -23,7 +16,8 @@ function curl_header_callback($curl_handle, $data) echo $data; } -$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +include 'server.inc'; +$host = curl_cli_server_start(); $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); diff --git a/ext/curl/tests/server.inc b/ext/curl/tests/server.inc new file mode 100644 index 0000000000..6d96a9850c --- /dev/null +++ b/ext/curl/tests/server.inc @@ -0,0 +1,56 @@ +<?php + +define ("PHP_CURL_SERVER_HOSTNAME", "localhost"); +define ("PHP_CURL_SERVER_PORT", 8964); +define ("PHP_CURL_SERVER_ADDRESS", PHP_CURL_SERVER_HOSTNAME.":".PHP_CURL_SERVER_PORT); + +function curl_cli_server_start() { + if(getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { + return getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + } + + $php_executable = getenv('TEST_PHP_EXECUTABLE'); + $doc_root = __DIR__; + $router = "responder/get.php"; + + $descriptorspec = array( + 0 => STDIN, + 1 => STDOUT, + 2 => STDERR, + ); + + if (substr(PHP_OS, 0, 3) == 'WIN') { + $cmd = "{$php_executable} -t {$doc_root} -n -S " . PHP_CURL_SERVER_ADDRESS; + $cmd .= " {$router}"; + $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} -n -S " . PHP_CURL_SERVER_ADDRESS; + $cmd .= " {$router}"; + $cmd .= " 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_CURL_SERVER_HOSTNAME, PHP_CURL_SERVER_PORT))) { + usleep(10000); + } + + if ($fp) { + fclose($fp); + } + + register_shutdown_function( + function($handle) use($router) { + 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. + return PHP_CURL_SERVER_ADDRESS; +} diff --git a/ext/curl/tests/skipif.inc b/ext/curl/tests/skipif.inc new file mode 100644 index 0000000000..62b252bcd1 --- /dev/null +++ b/ext/curl/tests/skipif.inc @@ -0,0 +1,7 @@ +<?php + if (!extension_loaded("curl")) exit("skip curl extension not loaded"); + if(false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { + if (php_sapi_name() != "cli") { + die("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); + } + } diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c index fd67d8bf52..6174756881 100644 --- a/ext/date/lib/parse_date.c +++ b/ext/date/lib/parse_date.c @@ -1,10 +1,10 @@ -/* Generated by re2c 0.13.5 on Thu Feb 6 07:35:53 2014 */ +/* Generated by re2c 0.13.5 on Tue May 13 17:01:57 2014 */ #line 1 "ext/date/lib/parse_date.re" /* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 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 | @@ -401,9 +401,12 @@ static timelib_sll timelib_meridian_with_check(char **ptr, timelib_sll h) { timelib_sll retval = 0; - while (!strchr("AaPp", **ptr)) { + while (**ptr && !strchr("AaPp", **ptr)) { ++*ptr; } + if(!**ptr) { + return TIMELIB_UNSET; + } if (**ptr == 'a' || **ptr == 'A') { if (h == 12) { retval = -12; @@ -837,11 +840,11 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) std: s->tok = cursor; s->len = 0; -#line 963 "ext/date/lib/parse_date.re" +#line 966 "ext/date/lib/parse_date.re" -#line 845 "ext/date/lib/parse_date.c" +#line 848 "ext/date/lib/parse_date.c" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -961,7 +964,7 @@ std: } yy2: YYDEBUG(2, *YYCURSOR); -#line 1049 "ext/date/lib/parse_date.re" +#line 1052 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("firstdayof | lastdayof"); TIMELIB_INIT; @@ -977,7 +980,7 @@ yy2: TIMELIB_DEINIT; return TIMELIB_LF_DAY_OF_MONTH; } -#line 981 "ext/date/lib/parse_date.c" +#line 984 "ext/date/lib/parse_date.c" yy3: YYDEBUG(3, *YYCURSOR); ++YYCURSOR; @@ -1000,7 +1003,7 @@ yy3: } yy4: YYDEBUG(4, *YYCURSOR); -#line 1643 "ext/date/lib/parse_date.re" +#line 1646 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("tzcorrection | tz"); @@ -1013,7 +1016,7 @@ yy4: TIMELIB_DEINIT; return TIMELIB_TIMEZONE; } -#line 1017 "ext/date/lib/parse_date.c" +#line 1020 "ext/date/lib/parse_date.c" yy5: YYDEBUG(5, *YYCURSOR); yych = *++YYCURSOR; @@ -1324,12 +1327,12 @@ yy12: if (yych <= '9') goto yy1385; yy13: YYDEBUG(13, *YYCURSOR); -#line 1738 "ext/date/lib/parse_date.re" +#line 1741 "ext/date/lib/parse_date.re" { add_error(s, "Unexpected character"); goto std; } -#line 1333 "ext/date/lib/parse_date.c" +#line 1336 "ext/date/lib/parse_date.c" yy14: YYDEBUG(14, *YYCURSOR); yych = *++YYCURSOR; @@ -2386,11 +2389,11 @@ yy49: if (yych <= '9') goto yy55; yy50: YYDEBUG(50, *YYCURSOR); -#line 1727 "ext/date/lib/parse_date.re" +#line 1730 "ext/date/lib/parse_date.re" { goto std; } -#line 2394 "ext/date/lib/parse_date.c" +#line 2397 "ext/date/lib/parse_date.c" yy51: YYDEBUG(51, *YYCURSOR); yych = *++YYCURSOR; @@ -2399,12 +2402,12 @@ yy52: YYDEBUG(52, *YYCURSOR); ++YYCURSOR; YYDEBUG(53, *YYCURSOR); -#line 1732 "ext/date/lib/parse_date.re" +#line 1735 "ext/date/lib/parse_date.re" { s->pos = cursor; s->line++; goto std; } -#line 2408 "ext/date/lib/parse_date.c" +#line 2411 "ext/date/lib/parse_date.c" yy54: YYDEBUG(54, *YYCURSOR); yych = *++YYCURSOR; @@ -2791,7 +2794,7 @@ yy72: if (yych == 's') goto yy74; yy73: YYDEBUG(73, *YYCURSOR); -#line 1711 "ext/date/lib/parse_date.re" +#line 1714 "ext/date/lib/parse_date.re" { timelib_ull i; DEBUG_OUTPUT("relative"); @@ -2806,7 +2809,7 @@ yy73: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 2810 "ext/date/lib/parse_date.c" +#line 2813 "ext/date/lib/parse_date.c" yy74: YYDEBUG(74, *YYCURSOR); yych = *++YYCURSOR; @@ -3568,7 +3571,7 @@ yy166: } yy167: YYDEBUG(167, *YYCURSOR); -#line 1574 "ext/date/lib/parse_date.re" +#line 1577 "ext/date/lib/parse_date.re" { const timelib_relunit* relunit; DEBUG_OUTPUT("daytext"); @@ -3585,7 +3588,7 @@ yy167: TIMELIB_DEINIT; return TIMELIB_WEEKDAY; } -#line 3589 "ext/date/lib/parse_date.c" +#line 3592 "ext/date/lib/parse_date.c" yy168: YYDEBUG(168, *YYCURSOR); yych = *++YYCURSOR; @@ -4105,7 +4108,7 @@ yy193: } yy194: YYDEBUG(194, *YYCURSOR); -#line 1633 "ext/date/lib/parse_date.re" +#line 1636 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("monthtext"); TIMELIB_INIT; @@ -4114,7 +4117,7 @@ yy194: TIMELIB_DEINIT; return TIMELIB_DATE_TEXT; } -#line 4118 "ext/date/lib/parse_date.c" +#line 4121 "ext/date/lib/parse_date.c" yy195: YYDEBUG(195, *YYCURSOR); ++YYCURSOR; @@ -4165,7 +4168,7 @@ yy198: } yy199: YYDEBUG(199, *YYCURSOR); -#line 1379 "ext/date/lib/parse_date.re" +#line 1382 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("datetextual | datenoyear"); @@ -4178,7 +4181,7 @@ yy199: TIMELIB_DEINIT; return TIMELIB_DATE_TEXT; } -#line 4182 "ext/date/lib/parse_date.c" +#line 4185 "ext/date/lib/parse_date.c" yy200: YYDEBUG(200, *YYCURSOR); yyaccept = 6; @@ -4447,7 +4450,7 @@ yy222: } yy223: YYDEBUG(223, *YYCURSOR); -#line 1681 "ext/date/lib/parse_date.re" +#line 1684 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz"); @@ -4476,7 +4479,7 @@ yy223: TIMELIB_DEINIT; return TIMELIB_SHORTDATE_WITH_TIME; } -#line 4480 "ext/date/lib/parse_date.c" +#line 4483 "ext/date/lib/parse_date.c" yy224: YYDEBUG(224, *YYCURSOR); yyaccept = 7; @@ -5174,7 +5177,7 @@ yy278: YYDEBUG(278, *YYCURSOR); ++YYCURSOR; YYDEBUG(279, *YYCURSOR); -#line 1657 "ext/date/lib/parse_date.re" +#line 1660 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("dateshortwithtimeshort12 | dateshortwithtimelong12"); TIMELIB_INIT; @@ -5197,7 +5200,7 @@ yy278: TIMELIB_DEINIT; return TIMELIB_SHORTDATE_WITH_TIME; } -#line 5201 "ext/date/lib/parse_date.c" +#line 5204 "ext/date/lib/parse_date.c" yy280: YYDEBUG(280, *YYCURSOR); yych = *++YYCURSOR; @@ -5375,7 +5378,7 @@ yy294: ++YYCURSOR; yy295: YYDEBUG(295, *YYCURSOR); -#line 1351 "ext/date/lib/parse_date.re" +#line 1354 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("datenoday"); @@ -5388,7 +5391,7 @@ yy295: TIMELIB_DEINIT; return TIMELIB_DATE_NO_DAY; } -#line 5392 "ext/date/lib/parse_date.c" +#line 5395 "ext/date/lib/parse_date.c" yy296: YYDEBUG(296, *YYCURSOR); yych = *++YYCURSOR; @@ -6608,7 +6611,7 @@ yy362: if (yych <= '9') goto yy365; yy364: YYDEBUG(364, *YYCURSOR); -#line 1495 "ext/date/lib/parse_date.re" +#line 1498 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("pgtextshort"); @@ -6621,7 +6624,7 @@ yy364: TIMELIB_DEINIT; return TIMELIB_PG_TEXT; } -#line 6625 "ext/date/lib/parse_date.c" +#line 6628 "ext/date/lib/parse_date.c" yy365: YYDEBUG(365, *YYCURSOR); yych = *++YYCURSOR; @@ -7259,7 +7262,7 @@ yy392: } yy393: YYDEBUG(393, *YYCURSOR); -#line 1553 "ext/date/lib/parse_date.re" +#line 1556 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("ago"); TIMELIB_INIT; @@ -7279,7 +7282,7 @@ yy393: TIMELIB_DEINIT; return TIMELIB_AGO; } -#line 7283 "ext/date/lib/parse_date.c" +#line 7286 "ext/date/lib/parse_date.c" yy394: YYDEBUG(394, *YYCURSOR); yyaccept = 5; @@ -9029,7 +9032,7 @@ yy454: ++YYCURSOR; yy455: YYDEBUG(455, *YYCURSOR); -#line 1256 "ext/date/lib/parse_date.re" +#line 1259 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("iso8601date4 | iso8601date2 | iso8601dateslash | dateslash"); TIMELIB_INIT; @@ -9040,7 +9043,7 @@ yy455: TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 9044 "ext/date/lib/parse_date.c" +#line 9047 "ext/date/lib/parse_date.c" yy456: YYDEBUG(456, *YYCURSOR); yyaccept = 0; @@ -9600,7 +9603,7 @@ yy475: } yy476: YYDEBUG(476, *YYCURSOR); -#line 1393 "ext/date/lib/parse_date.re" +#line 1396 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("datenoyearrev"); TIMELIB_INIT; @@ -9611,7 +9614,7 @@ yy476: TIMELIB_DEINIT; return TIMELIB_DATE_TEXT; } -#line 9615 "ext/date/lib/parse_date.c" +#line 9618 "ext/date/lib/parse_date.c" yy477: YYDEBUG(477, *YYCURSOR); yyaccept = 10; @@ -9752,7 +9755,7 @@ yy488: YYDEBUG(488, *YYCURSOR); ++YYCURSOR; YYDEBUG(489, *YYCURSOR); -#line 1111 "ext/date/lib/parse_date.re" +#line 1114 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("timetiny12 | timeshort12 | timelong12"); TIMELIB_INIT; @@ -9768,7 +9771,7 @@ yy488: TIMELIB_DEINIT; return TIMELIB_TIME12; } -#line 9772 "ext/date/lib/parse_date.c" +#line 9775 "ext/date/lib/parse_date.c" yy490: YYDEBUG(490, *YYCURSOR); yyaccept = 11; @@ -9781,7 +9784,7 @@ yy490: } yy491: YYDEBUG(491, *YYCURSOR); -#line 1148 "ext/date/lib/parse_date.re" +#line 1151 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("timeshort24 | timelong24 | iso8601long"); @@ -9806,7 +9809,7 @@ yy491: TIMELIB_DEINIT; return TIMELIB_TIME24_WITH_ZONE; } -#line 9810 "ext/date/lib/parse_date.c" +#line 9813 "ext/date/lib/parse_date.c" yy492: YYDEBUG(492, *YYCURSOR); yyaccept = 11; @@ -10116,7 +10119,7 @@ yy523: YYDEBUG(523, *YYCURSOR); ++YYCURSOR; YYDEBUG(524, *YYCURSOR); -#line 1128 "ext/date/lib/parse_date.re" +#line 1131 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("mssqltime"); TIMELIB_INIT; @@ -10135,7 +10138,7 @@ yy523: TIMELIB_DEINIT; return TIMELIB_TIME24_WITH_ZONE; } -#line 10139 "ext/date/lib/parse_date.c" +#line 10142 "ext/date/lib/parse_date.c" yy525: YYDEBUG(525, *YYCURSOR); yyaccept = 11; @@ -10241,7 +10244,7 @@ yy534: if (yych <= '9') goto yy541; yy535: YYDEBUG(535, *YYCURSOR); -#line 1310 "ext/date/lib/parse_date.re" +#line 1313 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("datefull"); @@ -10255,7 +10258,7 @@ yy535: TIMELIB_DEINIT; return TIMELIB_DATE_FULL; } -#line 10259 "ext/date/lib/parse_date.c" +#line 10262 "ext/date/lib/parse_date.c" yy536: YYDEBUG(536, *YYCURSOR); yych = *++YYCURSOR; @@ -10992,7 +10995,7 @@ yy605: YYDEBUG(606, *YYCURSOR); ++YYCURSOR; YYDEBUG(607, *YYCURSOR); -#line 1325 "ext/date/lib/parse_date.re" +#line 1328 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("pointed date YYYY"); TIMELIB_INIT; @@ -11003,7 +11006,7 @@ yy605: TIMELIB_DEINIT; return TIMELIB_DATE_FULL_POINTED; } -#line 11007 "ext/date/lib/parse_date.c" +#line 11010 "ext/date/lib/parse_date.c" yy608: YYDEBUG(608, *YYCURSOR); yyaccept = 11; @@ -11039,7 +11042,7 @@ yy611: if (yych <= '9') goto yy605; yy612: YYDEBUG(612, *YYCURSOR); -#line 1337 "ext/date/lib/parse_date.re" +#line 1340 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("pointed date YY"); @@ -11052,7 +11055,7 @@ yy612: TIMELIB_DEINIT; return TIMELIB_DATE_FULL_POINTED; } -#line 11056 "ext/date/lib/parse_date.c" +#line 11059 "ext/date/lib/parse_date.c" yy613: YYDEBUG(613, *YYCURSOR); yyaccept = 11; @@ -11693,7 +11696,7 @@ yy656: } yy657: YYDEBUG(657, *YYCURSOR); -#line 1296 "ext/date/lib/parse_date.re" +#line 1299 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("gnudateshort"); @@ -11706,7 +11709,7 @@ yy657: TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 11710 "ext/date/lib/parse_date.c" +#line 11713 "ext/date/lib/parse_date.c" yy658: YYDEBUG(658, *YYCURSOR); yyaccept = 13; @@ -11812,7 +11815,7 @@ yy666: } yy667: YYDEBUG(667, *YYCURSOR); -#line 1240 "ext/date/lib/parse_date.re" +#line 1243 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("americanshort | american"); @@ -11827,7 +11830,7 @@ yy667: TIMELIB_DEINIT; return TIMELIB_AMERICAN; } -#line 11831 "ext/date/lib/parse_date.c" +#line 11834 "ext/date/lib/parse_date.c" yy668: YYDEBUG(668, *YYCURSOR); yyaccept = 14; @@ -12060,7 +12063,7 @@ yy700: if (yych <= ':') goto yy704; yy701: YYDEBUG(701, *YYCURSOR); -#line 1523 "ext/date/lib/parse_date.re" +#line 1526 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("clf"); @@ -12080,7 +12083,7 @@ yy701: TIMELIB_DEINIT; return TIMELIB_CLF; } -#line 12084 "ext/date/lib/parse_date.c" +#line 12087 "ext/date/lib/parse_date.c" yy702: YYDEBUG(702, *YYCURSOR); yych = *++YYCURSOR; @@ -12632,7 +12635,7 @@ yy763: } yy764: YYDEBUG(764, *YYCURSOR); -#line 1268 "ext/date/lib/parse_date.re" +#line 1271 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("iso8601date2"); @@ -12645,7 +12648,7 @@ yy764: TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 12649 "ext/date/lib/parse_date.c" +#line 12652 "ext/date/lib/parse_date.c" yy765: YYDEBUG(765, *YYCURSOR); yych = *++YYCURSOR; @@ -12684,7 +12687,7 @@ yy771: YYDEBUG(771, *YYCURSOR); ++YYCURSOR; YYDEBUG(772, *YYCURSOR); -#line 1509 "ext/date/lib/parse_date.re" +#line 1512 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("pgtextreverse"); @@ -12697,7 +12700,7 @@ yy771: TIMELIB_DEINIT; return TIMELIB_PG_TEXT; } -#line 12701 "ext/date/lib/parse_date.c" +#line 12704 "ext/date/lib/parse_date.c" yy773: YYDEBUG(773, *YYCURSOR); yych = *++YYCURSOR; @@ -12835,7 +12838,7 @@ yy783: } yy784: YYDEBUG(784, *YYCURSOR); -#line 1544 "ext/date/lib/parse_date.re" +#line 1547 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("year4"); TIMELIB_INIT; @@ -12843,7 +12846,7 @@ yy784: TIMELIB_DEINIT; return TIMELIB_CLF; } -#line 12847 "ext/date/lib/parse_date.c" +#line 12850 "ext/date/lib/parse_date.c" yy785: YYDEBUG(785, *YYCURSOR); yych = *++YYCURSOR; @@ -12994,7 +12997,7 @@ yy793: } yy794: YYDEBUG(794, *YYCURSOR); -#line 1365 "ext/date/lib/parse_date.re" +#line 1368 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("datenodayrev"); @@ -13007,7 +13010,7 @@ yy794: TIMELIB_DEINIT; return TIMELIB_DATE_NO_DAY; } -#line 13011 "ext/date/lib/parse_date.c" +#line 13014 "ext/date/lib/parse_date.c" yy795: YYDEBUG(795, *YYCURSOR); yych = *++YYCURSOR; @@ -13222,7 +13225,7 @@ yy814: if (yych <= '7') goto yy817; yy815: YYDEBUG(815, *YYCURSOR); -#line 1476 "ext/date/lib/parse_date.re" +#line 1479 "ext/date/lib/parse_date.re" { timelib_sll w, d; DEBUG_OUTPUT("isoweek"); @@ -13240,7 +13243,7 @@ yy815: TIMELIB_DEINIT; return TIMELIB_ISO_WEEK; } -#line 13244 "ext/date/lib/parse_date.c" +#line 13247 "ext/date/lib/parse_date.c" yy816: YYDEBUG(816, *YYCURSOR); yych = *++YYCURSOR; @@ -13250,7 +13253,7 @@ yy817: YYDEBUG(817, *YYCURSOR); ++YYCURSOR; YYDEBUG(818, *YYCURSOR); -#line 1457 "ext/date/lib/parse_date.re" +#line 1460 "ext/date/lib/parse_date.re" { timelib_sll w, d; DEBUG_OUTPUT("isoweekday"); @@ -13268,7 +13271,7 @@ yy817: TIMELIB_DEINIT; return TIMELIB_ISO_WEEK; } -#line 13272 "ext/date/lib/parse_date.c" +#line 13275 "ext/date/lib/parse_date.c" yy819: YYDEBUG(819, *YYCURSOR); yych = *++YYCURSOR; @@ -13332,7 +13335,7 @@ yy821: } yy822: YYDEBUG(822, *YYCURSOR); -#line 1443 "ext/date/lib/parse_date.re" +#line 1446 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("pgydotd"); @@ -13345,7 +13348,7 @@ yy822: TIMELIB_DEINIT; return TIMELIB_PG_YEARDAY; } -#line 13349 "ext/date/lib/parse_date.c" +#line 13352 "ext/date/lib/parse_date.c" yy823: YYDEBUG(823, *YYCURSOR); yych = *++YYCURSOR; @@ -13448,7 +13451,7 @@ yy842: ++YYCURSOR; yy843: YYDEBUG(843, *YYCURSOR); -#line 1417 "ext/date/lib/parse_date.re" +#line 1420 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("xmlrpc | xmlrpcnocolon | soap | wddx | exif"); @@ -13473,7 +13476,7 @@ yy843: TIMELIB_DEINIT; return TIMELIB_XMLRPC_SOAP; } -#line 13477 "ext/date/lib/parse_date.c" +#line 13480 "ext/date/lib/parse_date.c" yy844: YYDEBUG(844, *YYCURSOR); yych = *++YYCURSOR; @@ -13735,7 +13738,7 @@ yy848: } yy849: YYDEBUG(849, *YYCURSOR); -#line 1405 "ext/date/lib/parse_date.re" +#line 1408 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("datenocolon"); TIMELIB_INIT; @@ -13746,7 +13749,7 @@ yy849: TIMELIB_DEINIT; return TIMELIB_DATE_NOCOLON; } -#line 13750 "ext/date/lib/parse_date.c" +#line 13753 "ext/date/lib/parse_date.c" yy850: YYDEBUG(850, *YYCURSOR); yych = *++YYCURSOR; @@ -14666,7 +14669,7 @@ yy973: if (yych <= '9') goto yy996; yy974: YYDEBUG(974, *YYCURSOR); -#line 1282 "ext/date/lib/parse_date.re" +#line 1285 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("gnudateshorter"); @@ -14679,7 +14682,7 @@ yy974: TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 14683 "ext/date/lib/parse_date.c" +#line 14686 "ext/date/lib/parse_date.c" yy975: YYDEBUG(975, *YYCURSOR); yyaccept = 22; @@ -15688,7 +15691,7 @@ yy1066: } yy1068: YYDEBUG(1068, *YYCURSOR); -#line 1174 "ext/date/lib/parse_date.re" +#line 1177 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("gnunocolon"); TIMELIB_INIT; @@ -15710,7 +15713,7 @@ yy1068: TIMELIB_DEINIT; return TIMELIB_GNU_NOCOLON; } -#line 15714 "ext/date/lib/parse_date.c" +#line 15717 "ext/date/lib/parse_date.c" yy1069: YYDEBUG(1069, *YYCURSOR); yych = *++YYCURSOR; @@ -15802,7 +15805,7 @@ yy1075: } yy1076: YYDEBUG(1076, *YYCURSOR); -#line 1220 "ext/date/lib/parse_date.re" +#line 1223 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("iso8601nocolon"); @@ -15821,7 +15824,7 @@ yy1076: TIMELIB_DEINIT; return TIMELIB_ISO_NOCOLON; } -#line 15825 "ext/date/lib/parse_date.c" +#line 15828 "ext/date/lib/parse_date.c" yy1077: YYDEBUG(1077, *YYCURSOR); yyaccept = 25; @@ -16719,7 +16722,7 @@ yy1117: } yy1118: YYDEBUG(1118, *YYCURSOR); -#line 1616 "ext/date/lib/parse_date.re" +#line 1619 "ext/date/lib/parse_date.re" { timelib_sll i; int behavior = 0; @@ -16735,7 +16738,7 @@ yy1118: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 16739 "ext/date/lib/parse_date.c" +#line 16742 "ext/date/lib/parse_date.c" yy1119: YYDEBUG(1119, *YYCURSOR); ++YYCURSOR; @@ -16786,7 +16789,7 @@ yy1126: YYDEBUG(1126, *YYCURSOR); ++YYCURSOR; YYDEBUG(1127, *YYCURSOR); -#line 1089 "ext/date/lib/parse_date.re" +#line 1092 "ext/date/lib/parse_date.re" { timelib_sll i; int behavior = 0; @@ -16807,7 +16810,7 @@ yy1126: TIMELIB_DEINIT; return TIMELIB_WEEK_DAY_OF_MONTH; } -#line 16811 "ext/date/lib/parse_date.c" +#line 16814 "ext/date/lib/parse_date.c" yy1128: YYDEBUG(1128, *YYCURSOR); yyaccept = 26; @@ -16915,7 +16918,7 @@ yy1141: } yy1142: YYDEBUG(1142, *YYCURSOR); -#line 1592 "ext/date/lib/parse_date.re" +#line 1595 "ext/date/lib/parse_date.re" { timelib_sll i; int behavior = 0; @@ -16938,7 +16941,7 @@ yy1142: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 16942 "ext/date/lib/parse_date.c" +#line 16945 "ext/date/lib/parse_date.c" yy1143: YYDEBUG(1143, *YYCURSOR); yych = *++YYCURSOR; @@ -19615,7 +19618,7 @@ yy1294: goto yy1298; yy1295: YYDEBUG(1295, *YYCURSOR); -#line 1066 "ext/date/lib/parse_date.re" +#line 1069 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("backof | frontof"); TIMELIB_INIT; @@ -19637,7 +19640,7 @@ yy1295: TIMELIB_DEINIT; return TIMELIB_LF_DAY_OF_MONTH; } -#line 19641 "ext/date/lib/parse_date.c" +#line 19644 "ext/date/lib/parse_date.c" yy1296: YYDEBUG(1296, *YYCURSOR); yyaccept = 28; @@ -21328,7 +21331,7 @@ yy1385: if (yych <= '9') goto yy1385; yy1387: YYDEBUG(1387, *YYCURSOR); -#line 1023 "ext/date/lib/parse_date.re" +#line 1026 "ext/date/lib/parse_date.re" { timelib_ull i; @@ -21353,7 +21356,7 @@ yy1387: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 21357 "ext/date/lib/parse_date.c" +#line 21360 "ext/date/lib/parse_date.c" yy1388: YYDEBUG(1388, *YYCURSOR); yych = *++YYCURSOR; @@ -21789,7 +21792,7 @@ yy1416: ++YYCURSOR; yy1417: YYDEBUG(1417, *YYCURSOR); -#line 1011 "ext/date/lib/parse_date.re" +#line 1014 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("tomorrow"); TIMELIB_INIT; @@ -21800,7 +21803,7 @@ yy1417: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 21804 "ext/date/lib/parse_date.c" +#line 21807 "ext/date/lib/parse_date.c" yy1418: YYDEBUG(1418, *YYCURSOR); yych = *++YYCURSOR; @@ -21835,7 +21838,7 @@ yy1419: } yy1420: YYDEBUG(1420, *YYCURSOR); -#line 1001 "ext/date/lib/parse_date.re" +#line 1004 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("midnight | today"); TIMELIB_INIT; @@ -21844,7 +21847,7 @@ yy1420: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 21848 "ext/date/lib/parse_date.c" +#line 21851 "ext/date/lib/parse_date.c" yy1421: YYDEBUG(1421, *YYCURSOR); yych = *++YYCURSOR; @@ -23856,7 +23859,7 @@ yy1499: } yy1500: YYDEBUG(1500, *YYCURSOR); -#line 980 "ext/date/lib/parse_date.re" +#line 983 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("now"); TIMELIB_INIT; @@ -23864,7 +23867,7 @@ yy1500: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 23868 "ext/date/lib/parse_date.c" +#line 23871 "ext/date/lib/parse_date.c" yy1501: YYDEBUG(1501, *YYCURSOR); yych = *++YYCURSOR; @@ -24003,7 +24006,7 @@ yy1507: } yy1508: YYDEBUG(1508, *YYCURSOR); -#line 989 "ext/date/lib/parse_date.re" +#line 992 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("noon"); TIMELIB_INIT; @@ -24014,7 +24017,7 @@ yy1508: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 24018 "ext/date/lib/parse_date.c" +#line 24021 "ext/date/lib/parse_date.c" yy1509: YYDEBUG(1509, *YYCURSOR); yyaccept = 0; @@ -24547,7 +24550,7 @@ yy1530: ++YYCURSOR; yy1531: YYDEBUG(1531, *YYCURSOR); -#line 968 "ext/date/lib/parse_date.re" +#line 971 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("yesterday"); TIMELIB_INIT; @@ -24558,7 +24561,7 @@ yy1531: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 24562 "ext/date/lib/parse_date.c" +#line 24565 "ext/date/lib/parse_date.c" yy1532: YYDEBUG(1532, *YYCURSOR); yyaccept = 0; @@ -24731,7 +24734,7 @@ yy1537: goto yy1531; } } -#line 1742 "ext/date/lib/parse_date.re" +#line 1745 "ext/date/lib/parse_date.re" } @@ -25090,7 +25093,11 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim break; case '\\': /* escaped char */ - ++fptr; + if(!fptr[1]) { + add_pbf_error(s, "Escaped character expected", string, begin); + break; + } + fptr++; if (*ptr == *fptr) { ++ptr; } else { diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re index ba64546de6..277935abec 100644 --- a/ext/date/lib/parse_date.re +++ b/ext/date/lib/parse_date.re @@ -399,9 +399,12 @@ static timelib_sll timelib_meridian_with_check(char **ptr, timelib_sll h) { timelib_sll retval = 0; - while (!strchr("AaPp", **ptr)) { + while (**ptr && !strchr("AaPp", **ptr)) { ++*ptr; } + if(!**ptr) { + return TIMELIB_UNSET; + } if (**ptr == 'a' || **ptr == 'A') { if (h == 12) { retval = -12; @@ -2097,7 +2100,11 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim break; case '\\': /* escaped char */ - ++fptr; + if(!fptr[1]) { + add_pbf_error(s, "Escaped character expected", string, begin); + break; + } + fptr++; if (*ptr == *fptr) { ++ptr; } else { diff --git a/ext/date/lib/timezonedb.h b/ext/date/lib/timezonedb.h index d2292d63b1..c270eeb807 100644 --- a/ext/date/lib/timezonedb.h +++ b/ext/date/lib/timezonedb.h @@ -13,575 +13,575 @@ const timelib_tzdb_index_entry timezonedb_idx_builtin[580] = { { "Africa/Brazzaville" , 0x00051C }, { "Africa/Bujumbura" , 0x000571 }, { "Africa/Cairo" , 0x0005B5 }, - { "Africa/Casablanca" , 0x000878 }, - { "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/Troll" , 0x0188EE }, - { "Antarctica/Vostok" , 0x018AC0 }, - { "Arctic/Longyearbyen" , 0x018B31 }, - { "Asia/Aden" , 0x018E63 }, - { "Asia/Almaty" , 0x018EB8 }, - { "Asia/Amman" , 0x019037 }, - { "Asia/Anadyr" , 0x0192ED }, - { "Asia/Aqtau" , 0x0194D2 }, - { "Asia/Aqtobe" , 0x0196D1 }, - { "Asia/Ashgabat" , 0x019889 }, - { "Asia/Ashkhabad" , 0x0199A6 }, - { "Asia/Baghdad" , 0x019AC3 }, - { "Asia/Bahrain" , 0x019C38 }, - { "Asia/Baku" , 0x019C9E }, - { "Asia/Bangkok" , 0x019F86 }, - { "Asia/Beirut" , 0x019FDB }, - { "Asia/Bishkek" , 0x01A2E8 }, - { "Asia/Brunei" , 0x01A494 }, - { "Asia/Calcutta" , 0x01A4F6 }, - { "Asia/Choibalsan" , 0x01A56F }, - { "Asia/Chongqing" , 0x01A6E8 }, - { "Asia/Chungking" , 0x01A7D7 }, - { "Asia/Colombo" , 0x01A886 }, - { "Asia/Dacca" , 0x01A922 }, - { "Asia/Damascus" , 0x01A9C8 }, - { "Asia/Dhaka" , 0x01AD18 }, - { "Asia/Dili" , 0x01ADBE }, - { "Asia/Dubai" , 0x01AE48 }, - { "Asia/Dushanbe" , 0x01AE9D }, - { "Asia/Gaza" , 0x01AFA0 }, - { "Asia/Harbin" , 0x01B2F3 }, - { "Asia/Hebron" , 0x01B3DA }, - { "Asia/Ho_Chi_Minh" , 0x01B736 }, - { "Asia/Hong_Kong" , 0x01B7AE }, - { "Asia/Hovd" , 0x01B970 }, - { "Asia/Irkutsk" , 0x01BAE8 }, - { "Asia/Istanbul" , 0x01BCCE }, - { "Asia/Jakarta" , 0x01C0BB }, - { "Asia/Jayapura" , 0x01C165 }, - { "Asia/Jerusalem" , 0x01C201 }, - { "Asia/Kabul" , 0x01C530 }, - { "Asia/Kamchatka" , 0x01C581 }, - { "Asia/Karachi" , 0x01C75D }, - { "Asia/Kashgar" , 0x01C812 }, - { "Asia/Kathmandu" , 0x01C8E3 }, - { "Asia/Katmandu" , 0x01C949 }, - { "Asia/Khandyga" , 0x01C9AF }, - { "Asia/Kolkata" , 0x01CBD4 }, - { "Asia/Krasnoyarsk" , 0x01CC4D }, - { "Asia/Kuala_Lumpur" , 0x01CE35 }, - { "Asia/Kuching" , 0x01CEF2 }, - { "Asia/Kuwait" , 0x01CFE0 }, - { "Asia/Macao" , 0x01D035 }, - { "Asia/Macau" , 0x01D170 }, - { "Asia/Magadan" , 0x01D2AB }, - { "Asia/Makassar" , 0x01D48D }, - { "Asia/Manila" , 0x01D552 }, - { "Asia/Muscat" , 0x01D5D7 }, - { "Asia/Nicosia" , 0x01D62C }, - { "Asia/Novokuznetsk" , 0x01D914 }, - { "Asia/Novosibirsk" , 0x01DB16 }, - { "Asia/Omsk" , 0x01DD01 }, - { "Asia/Oral" , 0x01DEE8 }, - { "Asia/Phnom_Penh" , 0x01E0B8 }, - { "Asia/Pontianak" , 0x01E130 }, - { "Asia/Pyongyang" , 0x01E1F2 }, - { "Asia/Qatar" , 0x01E25F }, - { "Asia/Qyzylorda" , 0x01E2C5 }, - { "Asia/Rangoon" , 0x01E49B }, - { "Asia/Riyadh" , 0x01E513 }, - { "Asia/Saigon" , 0x01E568 }, - { "Asia/Sakhalin" , 0x01E5E0 }, - { "Asia/Samarkand" , 0x01E7D7 }, - { "Asia/Seoul" , 0x01E90D }, - { "Asia/Shanghai" , 0x01E9B1 }, - { "Asia/Singapore" , 0x01EA91 }, - { "Asia/Taipei" , 0x01EB48 }, - { "Asia/Tashkent" , 0x01EC60 }, - { "Asia/Tbilisi" , 0x01ED91 }, - { "Asia/Tehran" , 0x01EF4B }, - { "Asia/Tel_Aviv" , 0x01F1B9 }, - { "Asia/Thimbu" , 0x01F4E8 }, - { "Asia/Thimphu" , 0x01F54E }, - { "Asia/Tokyo" , 0x01F5B4 }, - { "Asia/Ujung_Pandang" , 0x01F63D }, - { "Asia/Ulaanbaatar" , 0x01F6BA }, - { "Asia/Ulan_Bator" , 0x01F815 }, - { "Asia/Urumqi" , 0x01F962 }, - { "Asia/Ust-Nera" , 0x01FA29 }, - { "Asia/Vientiane" , 0x01FC2E }, - { "Asia/Vladivostok" , 0x01FCA6 }, - { "Asia/Yakutsk" , 0x01FE92 }, - { "Asia/Yekaterinburg" , 0x020077 }, - { "Asia/Yerevan" , 0x020282 }, - { "Atlantic/Azores" , 0x020482 }, - { "Atlantic/Bermuda" , 0x020985 }, - { "Atlantic/Canary" , 0x020C66 }, - { "Atlantic/Cape_Verde" , 0x020F3C }, - { "Atlantic/Faeroe" , 0x020FB5 }, - { "Atlantic/Faroe" , 0x021259 }, - { "Atlantic/Jan_Mayen" , 0x0214FD }, - { "Atlantic/Madeira" , 0x02182F }, - { "Atlantic/Reykjavik" , 0x021D38 }, - { "Atlantic/South_Georgia" , 0x021EF1 }, - { "Atlantic/St_Helena" , 0x022103 }, - { "Atlantic/Stanley" , 0x021F35 }, - { "Australia/ACT" , 0x022158 }, - { "Australia/Adelaide" , 0x022475 }, - { "Australia/Brisbane" , 0x0227A1 }, - { "Australia/Broken_Hill" , 0x022868 }, - { "Australia/Canberra" , 0x022BA6 }, - { "Australia/Currie" , 0x022EC3 }, - { "Australia/Darwin" , 0x0231F6 }, - { "Australia/Eucla" , 0x02327C }, - { "Australia/Hobart" , 0x023351 }, - { "Australia/LHI" , 0x0236AF }, - { "Australia/Lindeman" , 0x02394A }, - { "Australia/Lord_Howe" , 0x023A2B }, - { "Australia/Melbourne" , 0x023CD6 }, - { "Australia/North" , 0x023FFB }, - { "Australia/NSW" , 0x02406F }, - { "Australia/Perth" , 0x02438C }, - { "Australia/Queensland" , 0x024464 }, - { "Australia/South" , 0x024510 }, - { "Australia/Sydney" , 0x02482D }, - { "Australia/Tasmania" , 0x024B6A }, - { "Australia/Victoria" , 0x024EAF }, - { "Australia/West" , 0x0251CC }, - { "Australia/Yancowinna" , 0x025282 }, - { "Brazil/Acre" , 0x0255A4 }, - { "Brazil/DeNoronha" , 0x0256A8 }, - { "Brazil/East" , 0x0257C8 }, - { "Brazil/West" , 0x025AA5 }, - { "Canada/Atlantic" , 0x025B9D }, - { "Canada/Central" , 0x026085 }, - { "Canada/East-Saskatchewan" , 0x02698F }, - { "Canada/Eastern" , 0x02649F }, - { "Canada/Mountain" , 0x026B18 }, - { "Canada/Newfoundland" , 0x026E8E }, - { "Canada/Pacific" , 0x0273B9 }, - { "Canada/Saskatchewan" , 0x0277D2 }, - { "Canada/Yukon" , 0x02795B }, - { "CET" , 0x027C5E }, - { "Chile/Continental" , 0x027F67 }, - { "Chile/EasterIsland" , 0x028302 }, - { "CST6CDT" , 0x028644 }, - { "Cuba" , 0x028995 }, - { "EET" , 0x028D08 }, - { "Egypt" , 0x028FBB }, - { "Eire" , 0x02927E }, - { "EST" , 0x02978F }, - { "EST5EDT" , 0x0297D3 }, - { "Etc/GMT" , 0x029B24 }, - { "Etc/GMT+0" , 0x029BF0 }, - { "Etc/GMT+1" , 0x029C7A }, - { "Etc/GMT+10" , 0x029D07 }, - { "Etc/GMT+11" , 0x029D95 }, - { "Etc/GMT+12" , 0x029E23 }, - { "Etc/GMT+2" , 0x029F3E }, - { "Etc/GMT+3" , 0x029FCA }, - { "Etc/GMT+4" , 0x02A056 }, - { "Etc/GMT+5" , 0x02A0E2 }, - { "Etc/GMT+6" , 0x02A16E }, - { "Etc/GMT+7" , 0x02A1FA }, - { "Etc/GMT+8" , 0x02A286 }, - { "Etc/GMT+9" , 0x02A312 }, - { "Etc/GMT-0" , 0x029BAC }, - { "Etc/GMT-1" , 0x029C34 }, - { "Etc/GMT-10" , 0x029CC0 }, - { "Etc/GMT-11" , 0x029D4E }, - { "Etc/GMT-12" , 0x029DDC }, - { "Etc/GMT-13" , 0x029E6A }, - { "Etc/GMT-14" , 0x029EB1 }, - { "Etc/GMT-2" , 0x029EF8 }, - { "Etc/GMT-3" , 0x029F84 }, - { "Etc/GMT-4" , 0x02A010 }, - { "Etc/GMT-5" , 0x02A09C }, - { "Etc/GMT-6" , 0x02A128 }, - { "Etc/GMT-7" , 0x02A1B4 }, - { "Etc/GMT-8" , 0x02A240 }, - { "Etc/GMT-9" , 0x02A2CC }, - { "Etc/GMT0" , 0x029B68 }, - { "Etc/Greenwich" , 0x02A358 }, - { "Etc/UCT" , 0x02A39C }, - { "Etc/Universal" , 0x02A3E0 }, - { "Etc/UTC" , 0x02A424 }, - { "Etc/Zulu" , 0x02A468 }, - { "Europe/Amsterdam" , 0x02A4AC }, - { "Europe/Andorra" , 0x02A8EA }, - { "Europe/Athens" , 0x02AB66 }, - { "Europe/Belfast" , 0x02AEA9 }, - { "Europe/Belgrade" , 0x02B3E0 }, - { "Europe/Berlin" , 0x02B6A9 }, - { "Europe/Bratislava" , 0x02BA0D }, - { "Europe/Brussels" , 0x02BD3F }, - { "Europe/Bucharest" , 0x02C176 }, - { "Europe/Budapest" , 0x02C4A0 }, - { "Europe/Busingen" , 0x02C813 }, - { "Europe/Chisinau" , 0x02CACA }, - { "Europe/Copenhagen" , 0x02CE58 }, - { "Europe/Dublin" , 0x02D162 }, - { "Europe/Gibraltar" , 0x02D673 }, - { "Europe/Guernsey" , 0x02DACA }, - { "Europe/Helsinki" , 0x02E001 }, - { "Europe/Isle_of_Man" , 0x02E2B7 }, - { "Europe/Istanbul" , 0x02E7EE }, - { "Europe/Jersey" , 0x02EBDB }, - { "Europe/Kaliningrad" , 0x02F112 }, - { "Europe/Kiev" , 0x02F378 }, - { "Europe/Lisbon" , 0x02F694 }, - { "Europe/Ljubljana" , 0x02FB98 }, - { "Europe/London" , 0x02FE61 }, - { "Europe/Luxembourg" , 0x030398 }, - { "Europe/Madrid" , 0x0307EE }, - { "Europe/Malta" , 0x030BB4 }, - { "Europe/Mariehamn" , 0x030F6D }, - { "Europe/Minsk" , 0x031223 }, - { "Europe/Monaco" , 0x031431 }, - { "Europe/Moscow" , 0x03186C }, - { "Europe/Nicosia" , 0x031ABD }, - { "Europe/Oslo" , 0x031DA5 }, - { "Europe/Paris" , 0x0320D7 }, - { "Europe/Podgorica" , 0x03251D }, - { "Europe/Prague" , 0x0327E6 }, - { "Europe/Riga" , 0x032B18 }, - { "Europe/Rome" , 0x032E5D }, - { "Europe/Samara" , 0x033220 }, - { "Europe/San_Marino" , 0x033453 }, - { "Europe/Sarajevo" , 0x033816 }, - { "Europe/Simferopol" , 0x033ADF }, - { "Europe/Skopje" , 0x033D2B }, - { "Europe/Sofia" , 0x033FF4 }, - { "Europe/Stockholm" , 0x0342FC }, - { "Europe/Tallinn" , 0x0345AB }, - { "Europe/Tirane" , 0x0348E5 }, - { "Europe/Tiraspol" , 0x034BEB }, - { "Europe/Uzhgorod" , 0x034F79 }, - { "Europe/Vaduz" , 0x035290 }, - { "Europe/Vatican" , 0x03553F }, - { "Europe/Vienna" , 0x035902 }, - { "Europe/Vilnius" , 0x035C2F }, - { "Europe/Volgograd" , 0x035F6E }, - { "Europe/Warsaw" , 0x03616E }, - { "Europe/Zagreb" , 0x03654F }, - { "Europe/Zaporozhye" , 0x036818 }, - { "Europe/Zurich" , 0x036B59 }, - { "Factory" , 0x036E08 }, - { "GB" , 0x036E79 }, - { "GB-Eire" , 0x0373B0 }, - { "GMT" , 0x0378E7 }, - { "GMT+0" , 0x0379B3 }, - { "GMT-0" , 0x03796F }, - { "GMT0" , 0x03792B }, - { "Greenwich" , 0x0379F7 }, - { "Hongkong" , 0x037A3B }, - { "HST" , 0x037BFD }, - { "Iceland" , 0x037C41 }, - { "Indian/Antananarivo" , 0x037DFA }, - { "Indian/Chagos" , 0x037E6E }, - { "Indian/Christmas" , 0x037ED0 }, - { "Indian/Cocos" , 0x037F14 }, - { "Indian/Comoro" , 0x037F58 }, - { "Indian/Kerguelen" , 0x037FAD }, - { "Indian/Mahe" , 0x038002 }, - { "Indian/Maldives" , 0x038057 }, - { "Indian/Mauritius" , 0x0380AC }, - { "Indian/Mayotte" , 0x038122 }, - { "Indian/Reunion" , 0x038177 }, - { "Iran" , 0x0381CC }, - { "Israel" , 0x03843A }, - { "Jamaica" , 0x038769 }, - { "Japan" , 0x03882E }, - { "Kwajalein" , 0x0388B7 }, - { "Libya" , 0x03891A }, - { "MET" , 0x038A23 }, - { "Mexico/BajaNorte" , 0x038D2C }, - { "Mexico/BajaSur" , 0x039095 }, - { "Mexico/General" , 0x0392DA }, - { "MST" , 0x039538 }, - { "MST7MDT" , 0x03957C }, - { "Navajo" , 0x0398CD }, - { "NZ" , 0x039C46 }, - { "NZ-CHAT" , 0x039FC4 }, - { "Pacific/Apia" , 0x03A2AC }, - { "Pacific/Auckland" , 0x03A448 }, - { "Pacific/Chatham" , 0x03A7D4 }, - { "Pacific/Chuuk" , 0x03AACB }, - { "Pacific/Easter" , 0x03AB24 }, - { "Pacific/Efate" , 0x03AE82 }, - { "Pacific/Enderbury" , 0x03AF48 }, - { "Pacific/Fakaofo" , 0x03AFB6 }, - { "Pacific/Fiji" , 0x03B007 }, - { "Pacific/Funafuti" , 0x03B19A }, - { "Pacific/Galapagos" , 0x03B1DE }, - { "Pacific/Gambier" , 0x03B256 }, - { "Pacific/Guadalcanal" , 0x03B2BB }, - { "Pacific/Guam" , 0x03B310 }, - { "Pacific/Honolulu" , 0x03B366 }, - { "Pacific/Johnston" , 0x03B3DD }, - { "Pacific/Kiritimati" , 0x03B45C }, - { "Pacific/Kosrae" , 0x03B4C7 }, - { "Pacific/Kwajalein" , 0x03B524 }, - { "Pacific/Majuro" , 0x03B590 }, - { "Pacific/Marquesas" , 0x03B5EF }, - { "Pacific/Midway" , 0x03B656 }, - { "Pacific/Nauru" , 0x03B6E0 }, - { "Pacific/Niue" , 0x03B758 }, - { "Pacific/Norfolk" , 0x03B7B6 }, - { "Pacific/Noumea" , 0x03B80B }, - { "Pacific/Pago_Pago" , 0x03B89B }, - { "Pacific/Palau" , 0x03B924 }, - { "Pacific/Pitcairn" , 0x03B968 }, - { "Pacific/Pohnpei" , 0x03B9BD }, - { "Pacific/Ponape" , 0x03BA12 }, - { "Pacific/Port_Moresby" , 0x03BA57 }, - { "Pacific/Rarotonga" , 0x03BA9B }, - { "Pacific/Saipan" , 0x03BB77 }, - { "Pacific/Samoa" , 0x03BBDA }, - { "Pacific/Tahiti" , 0x03BC63 }, - { "Pacific/Tarawa" , 0x03BCC8 }, - { "Pacific/Tongatapu" , 0x03BD1C }, - { "Pacific/Truk" , 0x03BDA8 }, - { "Pacific/Wake" , 0x03BDED }, - { "Pacific/Wallis" , 0x03BE3D }, - { "Pacific/Yap" , 0x03BE81 }, - { "Poland" , 0x03BEC6 }, - { "Portugal" , 0x03C2A7 }, - { "PRC" , 0x03C7A3 }, - { "PST8PDT" , 0x03C854 }, - { "ROC" , 0x03CBA5 }, - { "ROK" , 0x03CCBD }, - { "Singapore" , 0x03CD61 }, - { "Turkey" , 0x03CE18 }, - { "UCT" , 0x03D205 }, - { "Universal" , 0x03D249 }, - { "US/Alaska" , 0x03D28D }, - { "US/Aleutian" , 0x03D5F6 }, - { "US/Arizona" , 0x03D95C }, - { "US/Central" , 0x03D9EA }, - { "US/East-Indiana" , 0x03E3F4 }, - { "US/Eastern" , 0x03DEF5 }, - { "US/Hawaii" , 0x03E65E }, - { "US/Indiana-Starke" , 0x03E6CF }, - { "US/Michigan" , 0x03EA40 }, - { "US/Mountain" , 0x03ED77 }, - { "US/Pacific" , 0x03F0F0 }, - { "US/Pacific-New" , 0x03F4F5 }, - { "US/Samoa" , 0x03F8FA }, - { "UTC" , 0x03F983 }, - { "W-SU" , 0x03FC7A }, - { "WET" , 0x03F9C7 }, - { "Zulu" , 0x03FEB4 }, + { "Africa/Casablanca" , 0x00099C }, + { "Africa/Ceuta" , 0x000BFE }, + { "Africa/Conakry" , 0x000F05 }, + { "Africa/Dakar" , 0x000F70 }, + { "Africa/Dar_es_Salaam" , 0x000FD6 }, + { "Africa/Djibouti" , 0x001043 }, + { "Africa/Douala" , 0x001098 }, + { "Africa/El_Aaiun" , 0x0010ED }, + { "Africa/Freetown" , 0x001318 }, + { "Africa/Gaborone" , 0x001427 }, + { "Africa/Harare" , 0x001494 }, + { "Africa/Johannesburg" , 0x0014E9 }, + { "Africa/Juba" , 0x001557 }, + { "Africa/Kampala" , 0x00166A }, + { "Africa/Khartoum" , 0x0016E9 }, + { "Africa/Kigali" , 0x0017FC }, + { "Africa/Kinshasa" , 0x001851 }, + { "Africa/Lagos" , 0x0018AC }, + { "Africa/Libreville" , 0x001901 }, + { "Africa/Lome" , 0x001956 }, + { "Africa/Luanda" , 0x00199A }, + { "Africa/Lubumbashi" , 0x0019EF }, + { "Africa/Lusaka" , 0x001A4A }, + { "Africa/Malabo" , 0x001A9F }, + { "Africa/Maputo" , 0x001B05 }, + { "Africa/Maseru" , 0x001B5A }, + { "Africa/Mbabane" , 0x001BC2 }, + { "Africa/Mogadishu" , 0x001C18 }, + { "Africa/Monrovia" , 0x001C73 }, + { "Africa/Nairobi" , 0x001CD9 }, + { "Africa/Ndjamena" , 0x001D58 }, + { "Africa/Niamey" , 0x001DC4 }, + { "Africa/Nouakchott" , 0x001E37 }, + { "Africa/Ouagadougou" , 0x001EA2 }, + { "Africa/Porto-Novo" , 0x001EF7 }, + { "Africa/Sao_Tome" , 0x001F5D }, + { "Africa/Timbuktu" , 0x001FB2 }, + { "Africa/Tripoli" , 0x00201D }, + { "Africa/Tunis" , 0x002126 }, + { "Africa/Windhoek" , 0x002238 }, + { "America/Adak" , 0x00247F }, + { "America/Anchorage" , 0x0027F5 }, + { "America/Anguilla" , 0x002B69 }, + { "America/Antigua" , 0x002BBE }, + { "America/Araguaina" , 0x002C24 }, + { "America/Argentina/Buenos_Aires" , 0x002D89 }, + { "America/Argentina/Catamarca" , 0x002F37 }, + { "America/Argentina/ComodRivadavia" , 0x0030F8 }, + { "America/Argentina/Cordoba" , 0x00329E }, + { "America/Argentina/Jujuy" , 0x003473 }, + { "America/Argentina/La_Rioja" , 0x003627 }, + { "America/Argentina/Mendoza" , 0x0037DF }, + { "America/Argentina/Rio_Gallegos" , 0x00399F }, + { "America/Argentina/Salta" , 0x003B54 }, + { "America/Argentina/San_Juan" , 0x003D00 }, + { "America/Argentina/San_Luis" , 0x003EB8 }, + { "America/Argentina/Tucuman" , 0x00407E }, + { "America/Argentina/Ushuaia" , 0x00423A }, + { "America/Aruba" , 0x0043F5 }, + { "America/Asuncion" , 0x00445B }, + { "America/Atikokan" , 0x004740 }, + { "America/Atka" , 0x004816 }, + { "America/Bahia" , 0x004B7C }, + { "America/Bahia_Banderas" , 0x004D0F }, + { "America/Barbados" , 0x004F88 }, + { "America/Belem" , 0x005022 }, + { "America/Belize" , 0x00511D }, + { "America/Blanc-Sablon" , 0x005299 }, + { "America/Boa_Vista" , 0x00534D }, + { "America/Bogota" , 0x005456 }, + { "America/Boise" , 0x0054C2 }, + { "America/Buenos_Aires" , 0x005859 }, + { "America/Cambridge_Bay" , 0x0059F2 }, + { "America/Campo_Grande" , 0x005D1A }, + { "America/Cancun" , 0x006009 }, + { "America/Caracas" , 0x00624B }, + { "America/Catamarca" , 0x0062B2 }, + { "America/Cayenne" , 0x006458 }, + { "America/Cayman" , 0x0064BA }, + { "America/Chicago" , 0x00650F }, + { "America/Chihuahua" , 0x006A26 }, + { "America/Coral_Harbour" , 0x006C91 }, + { "America/Cordoba" , 0x006D23 }, + { "America/Costa_Rica" , 0x006EC9 }, + { "America/Creston" , 0x006F53 }, + { "America/Cuiaba" , 0x006FDF }, + { "America/Curacao" , 0x0072BD }, + { "America/Danmarkshavn" , 0x007323 }, + { "America/Dawson" , 0x007467 }, + { "America/Dawson_Creek" , 0x007784 }, + { "America/Denver" , 0x00795E }, + { "America/Detroit" , 0x007CE4 }, + { "America/Dominica" , 0x008043 }, + { "America/Edmonton" , 0x008098 }, + { "America/Eirunepe" , 0x008450 }, + { "America/El_Salvador" , 0x008568 }, + { "America/Ensenada" , 0x0085DD }, + { "America/Fort_Wayne" , 0x008A84 }, + { "America/Fortaleza" , 0x008946 }, + { "America/Glace_Bay" , 0x008CEE }, + { "America/Godthab" , 0x009065 }, + { "America/Goose_Bay" , 0x009329 }, + { "America/Grand_Turk" , 0x0097E6 }, + { "America/Grenada" , 0x009A95 }, + { "America/Guadeloupe" , 0x009AEA }, + { "America/Guatemala" , 0x009B3F }, + { "America/Guayaquil" , 0x009BC8 }, + { "America/Guyana" , 0x009C25 }, + { "America/Halifax" , 0x009CA6 }, + { "America/Havana" , 0x00A1BC }, + { "America/Hermosillo" , 0x00A52F }, + { "America/Indiana/Indianapolis" , 0x00A60D }, + { "America/Indiana/Knox" , 0x00A89E }, + { "America/Indiana/Marengo" , 0x00AC35 }, + { "America/Indiana/Petersburg" , 0x00AEDB }, + { "America/Indiana/Tell_City" , 0x00B428 }, + { "America/Indiana/Vevay" , 0x00B6C1 }, + { "America/Indiana/Vincennes" , 0x00B8FC }, + { "America/Indiana/Winamac" , 0x00BBB0 }, + { "America/Indianapolis" , 0x00B1BE }, + { "America/Inuvik" , 0x00BE69 }, + { "America/Iqaluit" , 0x00C160 }, + { "America/Jamaica" , 0x00C482 }, + { "America/Jujuy" , 0x00C547 }, + { "America/Juneau" , 0x00C6F1 }, + { "America/Kentucky/Louisville" , 0x00CA6F }, + { "America/Kentucky/Monticello" , 0x00CE8D }, + { "America/Knox_IN" , 0x00D212 }, + { "America/Kralendijk" , 0x00D583 }, + { "America/La_Paz" , 0x00D5E9 }, + { "America/Lima" , 0x00D650 }, + { "America/Los_Angeles" , 0x00D6F8 }, + { "America/Louisville" , 0x00DB09 }, + { "America/Lower_Princes" , 0x00DEFE }, + { "America/Maceio" , 0x00DF64 }, + { "America/Managua" , 0x00E09E }, + { "America/Manaus" , 0x00E151 }, + { "America/Marigot" , 0x00E253 }, + { "America/Martinique" , 0x00E2A8 }, + { "America/Matamoros" , 0x00E314 }, + { "America/Mazatlan" , 0x00E56D }, + { "America/Mendoza" , 0x00E7DA }, + { "America/Menominee" , 0x00E98E }, + { "America/Merida" , 0x00ED0F }, + { "America/Metlakatla" , 0x00EF4A }, + { "America/Mexico_City" , 0x00F084 }, + { "America/Miquelon" , 0x00F2FF }, + { "America/Moncton" , 0x00F571 }, + { "America/Monterrey" , 0x00FA08 }, + { "America/Montevideo" , 0x00FC6B }, + { "America/Montreal" , 0x00FF7D }, + { "America/Montserrat" , 0x01046D }, + { "America/Nassau" , 0x0104C2 }, + { "America/New_York" , 0x010807 }, + { "America/Nipigon" , 0x010D12 }, + { "America/Nome" , 0x011063 }, + { "America/Noronha" , 0x0113E1 }, + { "America/North_Dakota/Beulah" , 0x011511 }, + { "America/North_Dakota/Center" , 0x0118A5 }, + { "America/North_Dakota/New_Salem" , 0x011C39 }, + { "America/Ojinaga" , 0x011FE2 }, + { "America/Panama" , 0x012243 }, + { "America/Pangnirtung" , 0x012298 }, + { "America/Paramaribo" , 0x0125CE }, + { "America/Phoenix" , 0x012660 }, + { "America/Port-au-Prince" , 0x01271E }, + { "America/Port_of_Spain" , 0x012A42 }, + { "America/Porto_Acre" , 0x01293E }, + { "America/Porto_Velho" , 0x012A97 }, + { "America/Puerto_Rico" , 0x012B8D }, + { "America/Rainy_River" , 0x012BF8 }, + { "America/Rankin_Inlet" , 0x012F30 }, + { "America/Recife" , 0x013216 }, + { "America/Regina" , 0x013340 }, + { "America/Resolute" , 0x0134FE }, + { "America/Rio_Branco" , 0x0137EF }, + { "America/Rosario" , 0x0138F7 }, + { "America/Santa_Isabel" , 0x013A9D }, + { "America/Santarem" , 0x013E40 }, + { "America/Santiago" , 0x013F45 }, + { "America/Santo_Domingo" , 0x0142EE }, + { "America/Sao_Paulo" , 0x0143B4 }, + { "America/Scoresbysund" , 0x0146C3 }, + { "America/Shiprock" , 0x0149B1 }, + { "America/Sitka" , 0x014D2A }, + { "America/St_Barthelemy" , 0x0150B2 }, + { "America/St_Johns" , 0x015107 }, + { "America/St_Kitts" , 0x01565A }, + { "America/St_Lucia" , 0x0156AF }, + { "America/St_Thomas" , 0x015704 }, + { "America/St_Vincent" , 0x015759 }, + { "America/Swift_Current" , 0x0157AE }, + { "America/Tegucigalpa" , 0x0158CF }, + { "America/Thule" , 0x01594E }, + { "America/Thunder_Bay" , 0x015B95 }, + { "America/Tijuana" , 0x015EDE }, + { "America/Toronto" , 0x016277 }, + { "America/Tortola" , 0x016797 }, + { "America/Vancouver" , 0x0167EC }, + { "America/Virgin" , 0x016C29 }, + { "America/Whitehorse" , 0x016C7E }, + { "America/Winnipeg" , 0x016F9B }, + { "America/Yakutat" , 0x0173DB }, + { "America/Yellowknife" , 0x017746 }, + { "Antarctica/Casey" , 0x017A56 }, + { "Antarctica/Davis" , 0x017AF3 }, + { "Antarctica/DumontDUrville" , 0x017B94 }, + { "Antarctica/Macquarie" , 0x017C26 }, + { "Antarctica/Mawson" , 0x017E6D }, + { "Antarctica/McMurdo" , 0x017EE9 }, + { "Antarctica/Palmer" , 0x018294 }, + { "Antarctica/Rothera" , 0x0185B0 }, + { "Antarctica/South_Pole" , 0x018626 }, + { "Antarctica/Syowa" , 0x0189A4 }, + { "Antarctica/Troll" , 0x018A12 }, + { "Antarctica/Vostok" , 0x018BE4 }, + { "Arctic/Longyearbyen" , 0x018C55 }, + { "Asia/Aden" , 0x018F87 }, + { "Asia/Almaty" , 0x018FDC }, + { "Asia/Amman" , 0x01915B }, + { "Asia/Anadyr" , 0x019411 }, + { "Asia/Aqtau" , 0x0195F6 }, + { "Asia/Aqtobe" , 0x0197F5 }, + { "Asia/Ashgabat" , 0x0199AD }, + { "Asia/Ashkhabad" , 0x019ACA }, + { "Asia/Baghdad" , 0x019BE7 }, + { "Asia/Bahrain" , 0x019D5C }, + { "Asia/Baku" , 0x019DC2 }, + { "Asia/Bangkok" , 0x01A0AA }, + { "Asia/Beirut" , 0x01A0FF }, + { "Asia/Bishkek" , 0x01A40C }, + { "Asia/Brunei" , 0x01A5B8 }, + { "Asia/Calcutta" , 0x01A61A }, + { "Asia/Choibalsan" , 0x01A693 }, + { "Asia/Chongqing" , 0x01A80C }, + { "Asia/Chungking" , 0x01A8FB }, + { "Asia/Colombo" , 0x01A9AA }, + { "Asia/Dacca" , 0x01AA46 }, + { "Asia/Damascus" , 0x01AAEC }, + { "Asia/Dhaka" , 0x01AE3C }, + { "Asia/Dili" , 0x01AEE2 }, + { "Asia/Dubai" , 0x01AF6C }, + { "Asia/Dushanbe" , 0x01AFC1 }, + { "Asia/Gaza" , 0x01B0C4 }, + { "Asia/Harbin" , 0x01B417 }, + { "Asia/Hebron" , 0x01B4FE }, + { "Asia/Ho_Chi_Minh" , 0x01B85A }, + { "Asia/Hong_Kong" , 0x01B8D2 }, + { "Asia/Hovd" , 0x01BA94 }, + { "Asia/Irkutsk" , 0x01BC0C }, + { "Asia/Istanbul" , 0x01BDF2 }, + { "Asia/Jakarta" , 0x01C1DF }, + { "Asia/Jayapura" , 0x01C289 }, + { "Asia/Jerusalem" , 0x01C325 }, + { "Asia/Kabul" , 0x01C654 }, + { "Asia/Kamchatka" , 0x01C6A5 }, + { "Asia/Karachi" , 0x01C881 }, + { "Asia/Kashgar" , 0x01C936 }, + { "Asia/Kathmandu" , 0x01CA07 }, + { "Asia/Katmandu" , 0x01CA6D }, + { "Asia/Khandyga" , 0x01CAD3 }, + { "Asia/Kolkata" , 0x01CCF8 }, + { "Asia/Krasnoyarsk" , 0x01CD71 }, + { "Asia/Kuala_Lumpur" , 0x01CF59 }, + { "Asia/Kuching" , 0x01D016 }, + { "Asia/Kuwait" , 0x01D104 }, + { "Asia/Macao" , 0x01D159 }, + { "Asia/Macau" , 0x01D294 }, + { "Asia/Magadan" , 0x01D3CF }, + { "Asia/Makassar" , 0x01D5B1 }, + { "Asia/Manila" , 0x01D676 }, + { "Asia/Muscat" , 0x01D6FB }, + { "Asia/Nicosia" , 0x01D750 }, + { "Asia/Novokuznetsk" , 0x01DA38 }, + { "Asia/Novosibirsk" , 0x01DC3A }, + { "Asia/Omsk" , 0x01DE25 }, + { "Asia/Oral" , 0x01E00C }, + { "Asia/Phnom_Penh" , 0x01E1DC }, + { "Asia/Pontianak" , 0x01E254 }, + { "Asia/Pyongyang" , 0x01E316 }, + { "Asia/Qatar" , 0x01E383 }, + { "Asia/Qyzylorda" , 0x01E3E9 }, + { "Asia/Rangoon" , 0x01E5BF }, + { "Asia/Riyadh" , 0x01E637 }, + { "Asia/Saigon" , 0x01E68C }, + { "Asia/Sakhalin" , 0x01E704 }, + { "Asia/Samarkand" , 0x01E8FB }, + { "Asia/Seoul" , 0x01EA31 }, + { "Asia/Shanghai" , 0x01EAD5 }, + { "Asia/Singapore" , 0x01EBB5 }, + { "Asia/Taipei" , 0x01EC6C }, + { "Asia/Tashkent" , 0x01ED84 }, + { "Asia/Tbilisi" , 0x01EEB5 }, + { "Asia/Tehran" , 0x01F06F }, + { "Asia/Tel_Aviv" , 0x01F2DD }, + { "Asia/Thimbu" , 0x01F60C }, + { "Asia/Thimphu" , 0x01F672 }, + { "Asia/Tokyo" , 0x01F6D8 }, + { "Asia/Ujung_Pandang" , 0x01F761 }, + { "Asia/Ulaanbaatar" , 0x01F7DE }, + { "Asia/Ulan_Bator" , 0x01F939 }, + { "Asia/Urumqi" , 0x01FA86 }, + { "Asia/Ust-Nera" , 0x01FB4D }, + { "Asia/Vientiane" , 0x01FD52 }, + { "Asia/Vladivostok" , 0x01FDCA }, + { "Asia/Yakutsk" , 0x01FFAF }, + { "Asia/Yekaterinburg" , 0x020194 }, + { "Asia/Yerevan" , 0x02039F }, + { "Atlantic/Azores" , 0x02059F }, + { "Atlantic/Bermuda" , 0x020AA2 }, + { "Atlantic/Canary" , 0x020D83 }, + { "Atlantic/Cape_Verde" , 0x021059 }, + { "Atlantic/Faeroe" , 0x0210D2 }, + { "Atlantic/Faroe" , 0x021376 }, + { "Atlantic/Jan_Mayen" , 0x02161A }, + { "Atlantic/Madeira" , 0x02194C }, + { "Atlantic/Reykjavik" , 0x021E55 }, + { "Atlantic/South_Georgia" , 0x02200E }, + { "Atlantic/St_Helena" , 0x022220 }, + { "Atlantic/Stanley" , 0x022052 }, + { "Australia/ACT" , 0x022275 }, + { "Australia/Adelaide" , 0x022592 }, + { "Australia/Brisbane" , 0x0228BE }, + { "Australia/Broken_Hill" , 0x022985 }, + { "Australia/Canberra" , 0x022CC3 }, + { "Australia/Currie" , 0x022FE0 }, + { "Australia/Darwin" , 0x023313 }, + { "Australia/Eucla" , 0x023399 }, + { "Australia/Hobart" , 0x02346E }, + { "Australia/LHI" , 0x0237CC }, + { "Australia/Lindeman" , 0x023A67 }, + { "Australia/Lord_Howe" , 0x023B48 }, + { "Australia/Melbourne" , 0x023DF3 }, + { "Australia/North" , 0x024118 }, + { "Australia/NSW" , 0x02418C }, + { "Australia/Perth" , 0x0244A9 }, + { "Australia/Queensland" , 0x024581 }, + { "Australia/South" , 0x02462D }, + { "Australia/Sydney" , 0x02494A }, + { "Australia/Tasmania" , 0x024C87 }, + { "Australia/Victoria" , 0x024FCC }, + { "Australia/West" , 0x0252E9 }, + { "Australia/Yancowinna" , 0x02539F }, + { "Brazil/Acre" , 0x0256C1 }, + { "Brazil/DeNoronha" , 0x0257C5 }, + { "Brazil/East" , 0x0258E5 }, + { "Brazil/West" , 0x025BC2 }, + { "Canada/Atlantic" , 0x025CBA }, + { "Canada/Central" , 0x0261A2 }, + { "Canada/East-Saskatchewan" , 0x026AAC }, + { "Canada/Eastern" , 0x0265BC }, + { "Canada/Mountain" , 0x026C35 }, + { "Canada/Newfoundland" , 0x026FAB }, + { "Canada/Pacific" , 0x0274D6 }, + { "Canada/Saskatchewan" , 0x0278EF }, + { "Canada/Yukon" , 0x027A78 }, + { "CET" , 0x027D7B }, + { "Chile/Continental" , 0x028084 }, + { "Chile/EasterIsland" , 0x02841F }, + { "CST6CDT" , 0x028761 }, + { "Cuba" , 0x028AB2 }, + { "EET" , 0x028E25 }, + { "Egypt" , 0x0290D8 }, + { "Eire" , 0x0294BF }, + { "EST" , 0x0299D0 }, + { "EST5EDT" , 0x029A14 }, + { "Etc/GMT" , 0x029D65 }, + { "Etc/GMT+0" , 0x029E31 }, + { "Etc/GMT+1" , 0x029EBB }, + { "Etc/GMT+10" , 0x029F48 }, + { "Etc/GMT+11" , 0x029FD6 }, + { "Etc/GMT+12" , 0x02A064 }, + { "Etc/GMT+2" , 0x02A17F }, + { "Etc/GMT+3" , 0x02A20B }, + { "Etc/GMT+4" , 0x02A297 }, + { "Etc/GMT+5" , 0x02A323 }, + { "Etc/GMT+6" , 0x02A3AF }, + { "Etc/GMT+7" , 0x02A43B }, + { "Etc/GMT+8" , 0x02A4C7 }, + { "Etc/GMT+9" , 0x02A553 }, + { "Etc/GMT-0" , 0x029DED }, + { "Etc/GMT-1" , 0x029E75 }, + { "Etc/GMT-10" , 0x029F01 }, + { "Etc/GMT-11" , 0x029F8F }, + { "Etc/GMT-12" , 0x02A01D }, + { "Etc/GMT-13" , 0x02A0AB }, + { "Etc/GMT-14" , 0x02A0F2 }, + { "Etc/GMT-2" , 0x02A139 }, + { "Etc/GMT-3" , 0x02A1C5 }, + { "Etc/GMT-4" , 0x02A251 }, + { "Etc/GMT-5" , 0x02A2DD }, + { "Etc/GMT-6" , 0x02A369 }, + { "Etc/GMT-7" , 0x02A3F5 }, + { "Etc/GMT-8" , 0x02A481 }, + { "Etc/GMT-9" , 0x02A50D }, + { "Etc/GMT0" , 0x029DA9 }, + { "Etc/Greenwich" , 0x02A599 }, + { "Etc/UCT" , 0x02A5DD }, + { "Etc/Universal" , 0x02A621 }, + { "Etc/UTC" , 0x02A665 }, + { "Etc/Zulu" , 0x02A6A9 }, + { "Europe/Amsterdam" , 0x02A6ED }, + { "Europe/Andorra" , 0x02AB2B }, + { "Europe/Athens" , 0x02ADA7 }, + { "Europe/Belfast" , 0x02B0EA }, + { "Europe/Belgrade" , 0x02B621 }, + { "Europe/Berlin" , 0x02B8EA }, + { "Europe/Bratislava" , 0x02BC4E }, + { "Europe/Brussels" , 0x02BF80 }, + { "Europe/Bucharest" , 0x02C3B7 }, + { "Europe/Budapest" , 0x02C6E1 }, + { "Europe/Busingen" , 0x02CA54 }, + { "Europe/Chisinau" , 0x02CD0B }, + { "Europe/Copenhagen" , 0x02D099 }, + { "Europe/Dublin" , 0x02D3A3 }, + { "Europe/Gibraltar" , 0x02D8B4 }, + { "Europe/Guernsey" , 0x02DD0B }, + { "Europe/Helsinki" , 0x02E242 }, + { "Europe/Isle_of_Man" , 0x02E4F8 }, + { "Europe/Istanbul" , 0x02EA2F }, + { "Europe/Jersey" , 0x02EE1C }, + { "Europe/Kaliningrad" , 0x02F353 }, + { "Europe/Kiev" , 0x02F5B9 }, + { "Europe/Lisbon" , 0x02F8D5 }, + { "Europe/Ljubljana" , 0x02FDD9 }, + { "Europe/London" , 0x0300A2 }, + { "Europe/Luxembourg" , 0x0305D9 }, + { "Europe/Madrid" , 0x030A2F }, + { "Europe/Malta" , 0x030DF5 }, + { "Europe/Mariehamn" , 0x0311AE }, + { "Europe/Minsk" , 0x031464 }, + { "Europe/Monaco" , 0x031672 }, + { "Europe/Moscow" , 0x031AAD }, + { "Europe/Nicosia" , 0x031D02 }, + { "Europe/Oslo" , 0x031FEA }, + { "Europe/Paris" , 0x03231C }, + { "Europe/Podgorica" , 0x032762 }, + { "Europe/Prague" , 0x032A2B }, + { "Europe/Riga" , 0x032D5D }, + { "Europe/Rome" , 0x0330A2 }, + { "Europe/Samara" , 0x033465 }, + { "Europe/San_Marino" , 0x033698 }, + { "Europe/Sarajevo" , 0x033A5B }, + { "Europe/Simferopol" , 0x033D24 }, + { "Europe/Skopje" , 0x033F70 }, + { "Europe/Sofia" , 0x034239 }, + { "Europe/Stockholm" , 0x034541 }, + { "Europe/Tallinn" , 0x0347F0 }, + { "Europe/Tirane" , 0x034B2A }, + { "Europe/Tiraspol" , 0x034E30 }, + { "Europe/Uzhgorod" , 0x0351BE }, + { "Europe/Vaduz" , 0x0354D5 }, + { "Europe/Vatican" , 0x035784 }, + { "Europe/Vienna" , 0x035B47 }, + { "Europe/Vilnius" , 0x035E74 }, + { "Europe/Volgograd" , 0x0361B3 }, + { "Europe/Warsaw" , 0x0363B3 }, + { "Europe/Zagreb" , 0x036794 }, + { "Europe/Zaporozhye" , 0x036A5D }, + { "Europe/Zurich" , 0x036D9E }, + { "Factory" , 0x03704D }, + { "GB" , 0x0370BE }, + { "GB-Eire" , 0x0375F5 }, + { "GMT" , 0x037B2C }, + { "GMT+0" , 0x037BF8 }, + { "GMT-0" , 0x037BB4 }, + { "GMT0" , 0x037B70 }, + { "Greenwich" , 0x037C3C }, + { "Hongkong" , 0x037C80 }, + { "HST" , 0x037E42 }, + { "Iceland" , 0x037E86 }, + { "Indian/Antananarivo" , 0x03803F }, + { "Indian/Chagos" , 0x0380B3 }, + { "Indian/Christmas" , 0x038115 }, + { "Indian/Cocos" , 0x038159 }, + { "Indian/Comoro" , 0x03819D }, + { "Indian/Kerguelen" , 0x0381F2 }, + { "Indian/Mahe" , 0x038247 }, + { "Indian/Maldives" , 0x03829C }, + { "Indian/Mauritius" , 0x0382F1 }, + { "Indian/Mayotte" , 0x038367 }, + { "Indian/Reunion" , 0x0383BC }, + { "Iran" , 0x038411 }, + { "Israel" , 0x03867F }, + { "Jamaica" , 0x0389AE }, + { "Japan" , 0x038A73 }, + { "Kwajalein" , 0x038AFC }, + { "Libya" , 0x038B5F }, + { "MET" , 0x038C68 }, + { "Mexico/BajaNorte" , 0x038F71 }, + { "Mexico/BajaSur" , 0x0392DA }, + { "Mexico/General" , 0x03951F }, + { "MST" , 0x03977D }, + { "MST7MDT" , 0x0397C1 }, + { "Navajo" , 0x039B12 }, + { "NZ" , 0x039E8B }, + { "NZ-CHAT" , 0x03A209 }, + { "Pacific/Apia" , 0x03A4F1 }, + { "Pacific/Auckland" , 0x03A68D }, + { "Pacific/Chatham" , 0x03AA19 }, + { "Pacific/Chuuk" , 0x03AD10 }, + { "Pacific/Easter" , 0x03AD69 }, + { "Pacific/Efate" , 0x03B0C7 }, + { "Pacific/Enderbury" , 0x03B18D }, + { "Pacific/Fakaofo" , 0x03B1FB }, + { "Pacific/Fiji" , 0x03B24C }, + { "Pacific/Funafuti" , 0x03B3DF }, + { "Pacific/Galapagos" , 0x03B423 }, + { "Pacific/Gambier" , 0x03B49B }, + { "Pacific/Guadalcanal" , 0x03B500 }, + { "Pacific/Guam" , 0x03B555 }, + { "Pacific/Honolulu" , 0x03B5AB }, + { "Pacific/Johnston" , 0x03B622 }, + { "Pacific/Kiritimati" , 0x03B6A1 }, + { "Pacific/Kosrae" , 0x03B70C }, + { "Pacific/Kwajalein" , 0x03B769 }, + { "Pacific/Majuro" , 0x03B7D5 }, + { "Pacific/Marquesas" , 0x03B834 }, + { "Pacific/Midway" , 0x03B89B }, + { "Pacific/Nauru" , 0x03B925 }, + { "Pacific/Niue" , 0x03B99D }, + { "Pacific/Norfolk" , 0x03B9FB }, + { "Pacific/Noumea" , 0x03BA50 }, + { "Pacific/Pago_Pago" , 0x03BAE0 }, + { "Pacific/Palau" , 0x03BB69 }, + { "Pacific/Pitcairn" , 0x03BBAD }, + { "Pacific/Pohnpei" , 0x03BC02 }, + { "Pacific/Ponape" , 0x03BC57 }, + { "Pacific/Port_Moresby" , 0x03BC9C }, + { "Pacific/Rarotonga" , 0x03BCE0 }, + { "Pacific/Saipan" , 0x03BDBC }, + { "Pacific/Samoa" , 0x03BE1F }, + { "Pacific/Tahiti" , 0x03BEA8 }, + { "Pacific/Tarawa" , 0x03BF0D }, + { "Pacific/Tongatapu" , 0x03BF61 }, + { "Pacific/Truk" , 0x03BFED }, + { "Pacific/Wake" , 0x03C032 }, + { "Pacific/Wallis" , 0x03C082 }, + { "Pacific/Yap" , 0x03C0C6 }, + { "Poland" , 0x03C10B }, + { "Portugal" , 0x03C4EC }, + { "PRC" , 0x03C9E8 }, + { "PST8PDT" , 0x03CA99 }, + { "ROC" , 0x03CDEA }, + { "ROK" , 0x03CF02 }, + { "Singapore" , 0x03CFA6 }, + { "Turkey" , 0x03D05D }, + { "UCT" , 0x03D44A }, + { "Universal" , 0x03D48E }, + { "US/Alaska" , 0x03D4D2 }, + { "US/Aleutian" , 0x03D83B }, + { "US/Arizona" , 0x03DBA1 }, + { "US/Central" , 0x03DC2F }, + { "US/East-Indiana" , 0x03E639 }, + { "US/Eastern" , 0x03E13A }, + { "US/Hawaii" , 0x03E8A3 }, + { "US/Indiana-Starke" , 0x03E914 }, + { "US/Michigan" , 0x03EC85 }, + { "US/Mountain" , 0x03EFBC }, + { "US/Pacific" , 0x03F335 }, + { "US/Pacific-New" , 0x03F73A }, + { "US/Samoa" , 0x03FB3F }, + { "UTC" , 0x03FBC8 }, + { "W-SU" , 0x03FEBF }, + { "WET" , 0x03FC0C }, + { "Zulu" , 0x0400FD }, }; /* This is a generated file, do not modify */ -const unsigned char timelib_timezone_db_data_builtin[261880] = { +const unsigned char timelib_timezone_db_data_builtin[262465] = { /* Africa/Abidjan */ @@ -711,8 +711,8 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { /* Africa/Cairo */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x45, 0x47, 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, 0x7A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0xC8, 0x93, 0xB4, 0xE0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xB6, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0xC8, 0x93, 0xB4, 0xE0, 0xC8, 0xFA, 0x7B, 0xD0, 0xC9, 0xFC, 0xEF, 0xE0, 0xCA, 0xC7, 0xE8, 0xD0, 0xCB, 0xCB, 0xAE, 0x60, 0xCC, 0xDF, 0x29, 0xD0, 0xCD, 0xAC, 0xE1, 0xE0, 0xCE, 0xC6, 0xF4, 0xD0, 0xCF, 0x8F, 0x66, 0xE0, 0xD0, 0xA9, 0x79, 0xD0, 0xD1, 0x84, 0x60, 0xE0, 0xD2, 0x8A, 0xAD, 0x50, 0xE8, 0x36, 0x63, 0x60, @@ -743,18 +743,36 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { 0x43, 0x3C, 0x55, 0xD0, 0x44, 0x51, 0x3E, 0xE0, 0x45, 0x12, 0xFD, 0x50, 0x46, 0x31, 0x20, 0xE0, 0x46, 0xE0, 0x6A, 0x50, 0x48, 0x11, 0x02, 0xE0, 0x48, 0xB7, 0x11, 0xD0, 0x49, 0xF0, 0xE4, 0xE0, 0x4A, 0x8D, 0xB9, 0x50, 0x4B, 0xDA, 0x01, 0x60, 0x4C, 0x61, 0xBD, 0xD0, 0x4C, 0x89, 0x58, 0xE0, -0x4C, 0xA4, 0xFA, 0x50, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, +0x4C, 0xA4, 0xFA, 0x50, 0x53, 0x75, 0x38, 0xE0, 0x53, 0xAC, 0x89, 0xD0, 0x53, 0xDA, 0xBC, 0x60, +0x54, 0x24, 0x82, 0x50, 0x55, 0x39, 0x6B, 0x60, 0x55, 0x79, 0xF6, 0xD0, 0x55, 0xB1, 0x63, 0xE0, +0x56, 0x04, 0x64, 0x50, 0x57, 0x22, 0x87, 0xE0, 0x57, 0x50, 0x9E, 0x50, 0x57, 0x7E, 0xD0, 0xE0, +0x57, 0xED, 0x80, 0xD0, 0x59, 0x02, 0x69, 0xE0, 0x59, 0x27, 0x45, 0xD0, 0x59, 0x55, 0x78, 0x60, +0x59, 0xCD, 0x62, 0xD0, 0x5A, 0xE2, 0x4B, 0xE0, 0x5A, 0xF4, 0xB2, 0xD0, 0x5B, 0x22, 0xE5, 0x60, +0x5B, 0xAD, 0x44, 0xD0, 0x5C, 0xC2, 0x2D, 0xE0, 0x5C, 0xCB, 0x5A, 0x50, 0x5C, 0xF9, 0x8C, 0xE0, +0x5D, 0x8D, 0x26, 0xD0, 0x5E, 0xD0, 0x34, 0x60, 0x5F, 0x6D, 0x08, 0xD0, 0x60, 0x9D, 0xA1, 0x60, +0x61, 0x56, 0x25, 0x50, 0x62, 0x74, 0x48, 0xE0, 0x63, 0x36, 0x07, 0x50, 0x64, 0x4A, 0xF0, 0x60, +0x65, 0x15, 0xE9, 0x50, 0x66, 0x2A, 0xD2, 0x60, 0x66, 0xF5, 0xCB, 0x50, 0x68, 0x0A, 0xB4, 0x60, +0x68, 0xD5, 0xAD, 0x50, 0x69, 0xEA, 0x96, 0x60, 0x6A, 0xB5, 0x8F, 0x50, 0x6B, 0xD3, 0xB2, 0xE0, +0x6C, 0x9E, 0xAB, 0xD0, 0x6D, 0xB3, 0x94, 0xE0, 0x6E, 0x7E, 0x8D, 0xD0, 0x6F, 0x93, 0x76, 0xE0, +0x70, 0x5E, 0x6F, 0xD0, 0x71, 0x73, 0x58, 0xE0, 0x72, 0x3E, 0x51, 0xD0, 0x73, 0x53, 0x3A, 0xE0, +0x74, 0x1E, 0x33, 0xD0, 0x75, 0x3C, 0x57, 0x60, 0x76, 0x07, 0x50, 0x50, 0x77, 0x1C, 0x39, 0x60, +0x77, 0xE7, 0x32, 0x50, 0x78, 0xFC, 0x1B, 0x60, 0x79, 0xC7, 0x14, 0x50, 0x7A, 0xDB, 0xFD, 0x60, +0x7B, 0xA6, 0xF6, 0x50, 0x7C, 0xBB, 0xDF, 0x60, 0x7D, 0x86, 0xD8, 0x50, 0x7E, 0x9B, 0xC1, 0x60, +0x7F, 0x66, 0xBA, 0x50, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, -0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 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, 0x01, 0x00, 0x03, 0x00, 0x00, -0x2A, 0x30, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x05, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x00, -0x00, 0x00, 0x1C, 0x20, 0x00, 0x05, 0x45, 0x45, 0x53, 0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x00, -0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB7, 0x2E, 0x88, 0x01, 0x42, 0x57, 0x88, 0x00, -0x00, 0x00, 0x00, +0x00, 0x01, 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, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x01, 0x00, 0x01, +0x00, 0x01, 0x02, 0x01, 0x00, 0x01, 0x02, 0x01, 0x00, 0x01, 0x02, 0x01, 0x00, 0x01, 0x02, 0x01, +0x00, 0x01, 0x02, 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, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x00, +0x00, 0x00, 0x1C, 0x20, 0x00, 0x05, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x00, 0x45, 0x45, 0x53, 0x54, +0x00, 0x45, 0x45, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xB7, 0x2E, 0x88, 0x01, +0x42, 0x57, 0x88, 0x00, 0x00, 0x00, 0x00, /* Africa/Casablanca */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4D, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -768,23 +786,23 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { 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, +0x52, 0x05, 0x9E, 0xA0, 0x52, 0x6C, 0x73, 0xA0, 0x53, 0x37, 0x7A, 0xA0, 0x53, 0xAE, 0x21, 0xA0, +0x53, 0xDC, 0x46, 0x20, 0x54, 0x4C, 0x55, 0xA0, 0x55, 0x17, 0x5C, 0xA0, 0x55, 0x7B, 0x8E, 0xA0, +0x55, 0xA9, 0xB3, 0x20, 0x56, 0x2C, 0x37, 0xA0, 0x56, 0xF7, 0x3E, 0xA0, 0x57, 0x52, 0x36, 0x20, +0x57, 0x80, 0x5A, 0xA0, 0x58, 0x15, 0x54, 0x20, 0x58, 0xD7, 0x20, 0xA0, 0x59, 0x1F, 0xA3, 0x20, +0x59, 0x57, 0x02, 0x20, 0x59, 0xF5, 0x36, 0x20, 0x5A, 0xB7, 0x02, 0xA0, 0x5A, 0xF6, 0x4A, 0xA0, +0x5B, 0x24, 0x6F, 0x20, 0x5B, 0xD5, 0x18, 0x20, 0x5C, 0xA0, 0x1F, 0x20, 0x5C, 0xCC, 0xF2, 0x20, +0x5C, 0xFB, 0x16, 0xA0, 0x5D, 0xB4, 0xFA, 0x20, 0x5E, 0x80, 0x01, 0x20, 0x5E, 0x9A, 0x5F, 0x20, +0x5E, 0xD1, 0xBE, 0x20, 0x5F, 0x94, 0xDC, 0x20, 0x60, 0x5F, 0xE3, 0x20, 0x60, 0x71, 0x06, 0xA0, +0x60, 0x9F, 0x2B, 0x20, 0x61, 0x7D, 0xF8, 0xA0, 0x62, 0x3F, 0xC5, 0x20, 0x62, 0x47, 0xAE, 0x20, +0x62, 0x75, 0xD2, 0xA0, 0x63, 0x5D, 0xDA, 0xA0, 0x64, 0x43, 0x3F, 0xA0, 0x65, 0x3D, 0xBC, 0xA0, +0x66, 0x19, 0xE7, 0x20, 0x67, 0x1D, 0x9E, 0xA0, 0x67, 0xF0, 0x8E, 0xA0, 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, +0x78, 0xD0, 0xD2, 0x20, 0x79, 0xEE, 0xE7, 0xA0, 0x7A, 0xB0, 0xB4, 0x20, 0x7B, 0xCD, 0x78, 0x20, +0x7C, 0x99, 0xD0, 0xA0, 0x7D, 0xA4, 0x1F, 0xA0, 0x7E, 0x79, 0xB2, 0xA0, 0x7F, 0x7A, 0xC7, 0x20, 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, @@ -901,23 +919,23 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { 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, +0x53, 0xAE, 0x21, 0xA0, 0x53, 0xDC, 0x46, 0x20, 0x54, 0x4C, 0x55, 0xA0, 0x55, 0x17, 0x5C, 0xA0, +0x55, 0x7B, 0x8E, 0xA0, 0x55, 0xA9, 0xB3, 0x20, 0x56, 0x2C, 0x37, 0xA0, 0x56, 0xF7, 0x3E, 0xA0, +0x57, 0x52, 0x36, 0x20, 0x57, 0x80, 0x5A, 0xA0, 0x58, 0x15, 0x54, 0x20, 0x58, 0xD7, 0x20, 0xA0, +0x59, 0x1F, 0xA3, 0x20, 0x59, 0x57, 0x02, 0x20, 0x59, 0xF5, 0x36, 0x20, 0x5A, 0xB7, 0x02, 0xA0, +0x5A, 0xF6, 0x4A, 0xA0, 0x5B, 0x24, 0x6F, 0x20, 0x5B, 0xD5, 0x18, 0x20, 0x5C, 0xA0, 0x1F, 0x20, +0x5C, 0xCC, 0xF2, 0x20, 0x5C, 0xFB, 0x16, 0xA0, 0x5D, 0xB4, 0xFA, 0x20, 0x5E, 0x80, 0x01, 0x20, +0x5E, 0x9A, 0x5F, 0x20, 0x5E, 0xD1, 0xBE, 0x20, 0x5F, 0x94, 0xDC, 0x20, 0x60, 0x5F, 0xE3, 0x20, +0x60, 0x71, 0x06, 0xA0, 0x60, 0x9F, 0x2B, 0x20, 0x61, 0x7D, 0xF8, 0xA0, 0x62, 0x3F, 0xC5, 0x20, +0x62, 0x47, 0xAE, 0x20, 0x62, 0x75, 0xD2, 0xA0, 0x63, 0x5D, 0xDA, 0xA0, 0x64, 0x43, 0x3F, 0xA0, +0x65, 0x3D, 0xBC, 0xA0, 0x66, 0x19, 0xE7, 0x20, 0x67, 0x1D, 0x9E, 0xA0, 0x67, 0xF0, 0x8E, 0xA0, 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, +0x7B, 0xCD, 0x78, 0x20, 0x7C, 0x99, 0xD0, 0xA0, 0x7D, 0xA4, 0x1F, 0xA0, 0x7E, 0x79, 0xB2, 0xA0, +0x7F, 0x7A, 0xC7, 0x20, 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, @@ -9535,7 +9553,7 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { /* Asia/Vladivostok */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x52, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x16, 0xA7, 0x59, 0x47, 0x50, +0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0F, 0xA7, 0x59, 0x47, 0x50, 0xB5, 0xA3, 0xB6, 0xF0, 0x15, 0x27, 0x45, 0x60, 0x16, 0x18, 0x79, 0xD0, 0x17, 0x08, 0x78, 0xE0, 0x17, 0xF9, 0xAD, 0x50, 0x18, 0xE9, 0xAC, 0x60, 0x19, 0xDA, 0xE0, 0xD0, 0x1A, 0xCC, 0x31, 0x60, 0x1B, 0xBC, 0x3E, 0x80, 0x1C, 0xAC, 0x2F, 0x80, 0x1D, 0x9C, 0x20, 0x80, 0x1E, 0x8C, 0x11, 0x80, @@ -9558,12 +9576,12 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x08, 0x00, 0x00, 0x7B, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x04, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x09, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x04, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x04, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x09, -0x00, 0x00, 0x8C, 0xA0, 0x01, 0x0F, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x09, 0x00, 0x00, 0x9A, 0xB0, +0x00, 0x00, 0x8C, 0xA0, 0x01, 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x04, 0x00, 0x00, 0x9A, 0xB0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x56, 0x4C, 0x41, 0x54, 0x00, 0x56, 0x4C, 0x41, 0x53, 0x54, -0x00, 0x56, 0x4C, 0x41, 0x53, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0x32, 0x3A, 0x01, 0xDB, -0xF8, 0xF5, 0x00, 0x00, 0x00, 0x16, 0x4D, 0x6F, 0x73, 0x63, 0x6F, 0x77, 0x2B, 0x30, 0x37, 0x20, -0x2D, 0x20, 0x41, 0x6D, 0x75, 0x72, 0x20, 0x52, 0x69, 0x76, 0x65, 0x72, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xCB, 0x32, 0x3A, 0x01, 0xDB, 0xF8, 0xF5, 0x00, 0x00, 0x00, 0x16, 0x4D, +0x6F, 0x73, 0x63, 0x6F, 0x77, 0x2B, 0x30, 0x37, 0x20, 0x2D, 0x20, 0x41, 0x6D, 0x75, 0x72, 0x20, +0x52, 0x69, 0x76, 0x65, 0x72, /* Asia/Yakutsk */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x52, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -12035,8 +12053,8 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { /* Egypt */ 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, 0x7A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0xC8, 0x93, 0xB4, 0xE0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xB6, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0xC8, 0x93, 0xB4, 0xE0, 0xC8, 0xFA, 0x7B, 0xD0, 0xC9, 0xFC, 0xEF, 0xE0, 0xCA, 0xC7, 0xE8, 0xD0, 0xCB, 0xCB, 0xAE, 0x60, 0xCC, 0xDF, 0x29, 0xD0, 0xCD, 0xAC, 0xE1, 0xE0, 0xCE, 0xC6, 0xF4, 0xD0, 0xCF, 0x8F, 0x66, 0xE0, 0xD0, 0xA9, 0x79, 0xD0, 0xD1, 0x84, 0x60, 0xE0, 0xD2, 0x8A, 0xAD, 0x50, 0xE8, 0x36, 0x63, 0x60, @@ -12067,18 +12085,36 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { 0x43, 0x3C, 0x55, 0xD0, 0x44, 0x51, 0x3E, 0xE0, 0x45, 0x12, 0xFD, 0x50, 0x46, 0x31, 0x20, 0xE0, 0x46, 0xE0, 0x6A, 0x50, 0x48, 0x11, 0x02, 0xE0, 0x48, 0xB7, 0x11, 0xD0, 0x49, 0xF0, 0xE4, 0xE0, 0x4A, 0x8D, 0xB9, 0x50, 0x4B, 0xDA, 0x01, 0x60, 0x4C, 0x61, 0xBD, 0xD0, 0x4C, 0x89, 0x58, 0xE0, -0x4C, 0xA4, 0xFA, 0x50, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, +0x4C, 0xA4, 0xFA, 0x50, 0x53, 0x75, 0x38, 0xE0, 0x53, 0xAC, 0x89, 0xD0, 0x53, 0xDA, 0xBC, 0x60, +0x54, 0x24, 0x82, 0x50, 0x55, 0x39, 0x6B, 0x60, 0x55, 0x79, 0xF6, 0xD0, 0x55, 0xB1, 0x63, 0xE0, +0x56, 0x04, 0x64, 0x50, 0x57, 0x22, 0x87, 0xE0, 0x57, 0x50, 0x9E, 0x50, 0x57, 0x7E, 0xD0, 0xE0, +0x57, 0xED, 0x80, 0xD0, 0x59, 0x02, 0x69, 0xE0, 0x59, 0x27, 0x45, 0xD0, 0x59, 0x55, 0x78, 0x60, +0x59, 0xCD, 0x62, 0xD0, 0x5A, 0xE2, 0x4B, 0xE0, 0x5A, 0xF4, 0xB2, 0xD0, 0x5B, 0x22, 0xE5, 0x60, +0x5B, 0xAD, 0x44, 0xD0, 0x5C, 0xC2, 0x2D, 0xE0, 0x5C, 0xCB, 0x5A, 0x50, 0x5C, 0xF9, 0x8C, 0xE0, +0x5D, 0x8D, 0x26, 0xD0, 0x5E, 0xD0, 0x34, 0x60, 0x5F, 0x6D, 0x08, 0xD0, 0x60, 0x9D, 0xA1, 0x60, +0x61, 0x56, 0x25, 0x50, 0x62, 0x74, 0x48, 0xE0, 0x63, 0x36, 0x07, 0x50, 0x64, 0x4A, 0xF0, 0x60, +0x65, 0x15, 0xE9, 0x50, 0x66, 0x2A, 0xD2, 0x60, 0x66, 0xF5, 0xCB, 0x50, 0x68, 0x0A, 0xB4, 0x60, +0x68, 0xD5, 0xAD, 0x50, 0x69, 0xEA, 0x96, 0x60, 0x6A, 0xB5, 0x8F, 0x50, 0x6B, 0xD3, 0xB2, 0xE0, +0x6C, 0x9E, 0xAB, 0xD0, 0x6D, 0xB3, 0x94, 0xE0, 0x6E, 0x7E, 0x8D, 0xD0, 0x6F, 0x93, 0x76, 0xE0, +0x70, 0x5E, 0x6F, 0xD0, 0x71, 0x73, 0x58, 0xE0, 0x72, 0x3E, 0x51, 0xD0, 0x73, 0x53, 0x3A, 0xE0, +0x74, 0x1E, 0x33, 0xD0, 0x75, 0x3C, 0x57, 0x60, 0x76, 0x07, 0x50, 0x50, 0x77, 0x1C, 0x39, 0x60, +0x77, 0xE7, 0x32, 0x50, 0x78, 0xFC, 0x1B, 0x60, 0x79, 0xC7, 0x14, 0x50, 0x7A, 0xDB, 0xFD, 0x60, +0x7B, 0xA6, 0xF6, 0x50, 0x7C, 0xBB, 0xDF, 0x60, 0x7D, 0x86, 0xD8, 0x50, 0x7E, 0x9B, 0xC1, 0x60, +0x7F, 0x66, 0xBA, 0x50, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, -0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 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, 0x01, 0x00, 0x03, 0x00, 0x00, -0x2A, 0x30, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x05, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x00, -0x00, 0x00, 0x1C, 0x20, 0x00, 0x05, 0x45, 0x45, 0x53, 0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x00, -0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, -0x00, 0x00, 0x00, +0x00, 0x01, 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, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x01, 0x00, 0x01, +0x00, 0x01, 0x02, 0x01, 0x00, 0x01, 0x02, 0x01, 0x00, 0x01, 0x02, 0x01, 0x00, 0x01, 0x02, 0x01, +0x00, 0x01, 0x02, 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, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x00, +0x00, 0x00, 0x1C, 0x20, 0x00, 0x05, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x00, 0x45, 0x45, 0x53, 0x54, +0x00, 0x45, 0x45, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, +0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, /* Eire */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -14405,7 +14441,7 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { /* Europe/Moscow */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x52, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x1E, 0x9B, 0x5F, 0x1E, 0xD8, +0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x22, 0x9B, 0x5F, 0x1E, 0xD8, 0x9D, 0x3E, 0xF2, 0x98, 0x9E, 0x2A, 0xEF, 0x18, 0x9E, 0xF7, 0x39, 0x88, 0x9F, 0x84, 0x58, 0x18, 0xA0, 0xD8, 0x6D, 0x08, 0xA1, 0x00, 0x16, 0x28, 0xA1, 0x3C, 0xA6, 0x40, 0xA4, 0x10, 0x6D, 0xC0, 0xA4, 0x3D, 0x32, 0xB0, 0xA5, 0x15, 0x68, 0xB0, 0xA5, 0x3D, 0x03, 0xC0, 0xA7, 0x1E, 0x45, 0x50, @@ -14432,15 +14468,15 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x0C, 0x00, 0x00, 0x23, 0x28, 0x00, 0x00, 0x00, 0x00, 0x31, 0x68, 0x01, 0x04, 0x00, 0x00, 0x23, 0x58, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x78, 0x01, 0x08, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0D, 0x00, 0x00, 0x38, 0x40, 0x01, 0x11, 0x00, 0x00, 0x46, 0x50, -0x01, 0x11, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x15, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0D, 0x00, 0x00, -0x38, 0x40, 0x01, 0x11, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x19, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x15, +0x01, 0x15, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x19, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0D, 0x00, 0x00, +0x38, 0x40, 0x01, 0x11, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x19, 0x00, 0x00, 0x38, 0x40, 0x00, 0x0D, 0x4D, 0x4D, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x44, -0x53, 0x54, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x4D, 0x53, 0x44, 0x00, 0x45, 0x45, 0x54, 0x00, 0x45, -0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, -0x65, 0x98, 0x01, 0x4C, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x17, 0x4D, 0x6F, 0x73, 0x63, 0x6F, 0x77, -0x2B, 0x30, 0x30, 0x20, 0x2D, 0x20, 0x77, 0x65, 0x73, 0x74, 0x20, 0x52, 0x75, 0x73, 0x73, 0x69, -0x61, +0x53, 0x54, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x4D, 0x53, 0x44, 0x00, 0x4D, 0x53, 0x4D, 0x00, 0x45, +0x45, 0x54, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xDE, 0x65, 0x98, 0x01, 0x4C, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x17, 0x4D, 0x6F, +0x73, 0x63, 0x6F, 0x77, 0x2B, 0x30, 0x30, 0x20, 0x2D, 0x20, 0x77, 0x65, 0x73, 0x74, 0x20, 0x52, +0x75, 0x73, 0x73, 0x69, 0x61, /* Europe/Nicosia */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -18393,7 +18429,7 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { /* W-SU */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x1E, 0x9B, 0x5F, 0x1E, 0xD8, +0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x22, 0x9B, 0x5F, 0x1E, 0xD8, 0x9D, 0x3E, 0xF2, 0x98, 0x9E, 0x2A, 0xEF, 0x18, 0x9E, 0xF7, 0x39, 0x88, 0x9F, 0x84, 0x58, 0x18, 0xA0, 0xD8, 0x6D, 0x08, 0xA1, 0x00, 0x16, 0x28, 0xA1, 0x3C, 0xA6, 0x40, 0xA4, 0x10, 0x6D, 0xC0, 0xA4, 0x3D, 0x32, 0xB0, 0xA5, 0x15, 0x68, 0xB0, 0xA5, 0x3D, 0x03, 0xC0, 0xA7, 0x1E, 0x45, 0x50, @@ -18420,13 +18456,13 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x0C, 0x00, 0x00, 0x23, 0x28, 0x00, 0x00, 0x00, 0x00, 0x31, 0x68, 0x01, 0x04, 0x00, 0x00, 0x23, 0x58, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x78, 0x01, 0x08, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0D, 0x00, 0x00, 0x38, 0x40, 0x01, 0x11, 0x00, 0x00, 0x46, 0x50, -0x01, 0x11, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x15, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0D, 0x00, 0x00, -0x38, 0x40, 0x01, 0x11, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x19, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x15, +0x01, 0x15, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x19, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0D, 0x00, 0x00, +0x38, 0x40, 0x01, 0x11, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x19, 0x00, 0x00, 0x38, 0x40, 0x00, 0x0D, 0x4D, 0x4D, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x44, -0x53, 0x54, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x4D, 0x53, 0x44, 0x00, 0x45, 0x45, 0x54, 0x00, 0x45, -0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, -0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, +0x53, 0x54, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x4D, 0x53, 0x44, 0x00, 0x4D, 0x53, 0x4D, 0x00, 0x45, +0x45, 0x54, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, /* Zulu */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -18435,4 +18471,4 @@ const unsigned char timelib_timezone_db_data_builtin[261880] = { 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 = { "2014.2", 580, timezonedb_idx_builtin, timelib_timezone_db_data_builtin }; +const timelib_tzdb timezonedb_builtin = { "2014.5", 580, timezonedb_idx_builtin, timelib_timezone_db_data_builtin }; diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 69f990ca51..700929154c 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2218,7 +2218,7 @@ static HashTable *date_object_get_properties(zval *object TSRMLS_DC) /* first we add the date and time in ISO format */ MAKE_STD_ZVAL(zv); - ZVAL_STRING(zv, date_format("Y-m-d H:i:s", 12, dateobj->time, 1), 0); + ZVAL_STRING(zv, date_format("Y-m-d H:i:s.u", 14, dateobj->time, 1), 0); zend_hash_update(props, "date", 5, &zv, sizeof(zv), NULL); /* then we add the timezone name (or similar) */ @@ -2582,6 +2582,8 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message); } if (err && err->error_count) { + timelib_time_dtor(dateobj->time); + dateobj->time = 0; return 0; } @@ -2729,7 +2731,9 @@ PHP_METHOD(DateTime, __construct) zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO!", &time_str, &time_str_len, &timezone_object, date_ce_timezone)) { - php_date_initialize(zend_object_store_get_object(getThis() TSRMLS_CC), time_str, time_str_len, NULL, timezone_object, 1 TSRMLS_CC); + if (!php_date_initialize(zend_object_store_get_object(getThis() TSRMLS_CC), time_str, time_str_len, NULL, timezone_object, 1 TSRMLS_CC)) { + ZVAL_NULL(getThis()); + } } zend_restore_error_handling(&error_handling TSRMLS_CC); } diff --git a/ext/date/tests/012.phpt b/ext/date/tests/012.phpt index 0577f18233..be7e4e32af 100644 --- a/ext/date/tests/012.phpt +++ b/ext/date/tests/012.phpt @@ -21,7 +21,7 @@ echo "Done\n"; --EXPECTF-- object(DateTime)#1 (3) { ["date"]=> - string(19) "2006-01-23 00:00:00" + string(26) "2006-01-23 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -34,7 +34,7 @@ bool(false) string(19) "2006/01/23 00:00:00" object(DateTime)#1 (3) { ["date"]=> - string(19) "2006-01-30 00:00:00" + string(26) "2006-01-30 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -43,7 +43,7 @@ object(DateTime)#1 (3) { string(19) "2006/01/30 00:00:00" object(DateTime)#1 (3) { ["date"]=> - string(19) "2007-12-10 00:00:00" + string(26) "2007-12-10 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/013.phpt b/ext/date/tests/013.phpt index 60fac24f6e..266dafe06a 100644 --- a/ext/date/tests/013.phpt +++ b/ext/date/tests/013.phpt @@ -21,7 +21,7 @@ echo "Done\n"; --EXPECTF-- object(DateTime)#%d (3) { ["date"]=> - string(19) "2006-12-12 00:00:00" + string(26) "2006-12-12 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -38,7 +38,7 @@ bool(false) string(19) "2006.12.12 00:00:00" object(DateTime)#1 (3) { ["date"]=> - string(19) "2006-02-15 00:00:00" + string(26) "2006-02-15 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -47,7 +47,7 @@ object(DateTime)#1 (3) { string(19) "2006.02.15 00:00:00" object(DateTime)#1 (3) { ["date"]=> - string(19) "2008-01-29 00:00:00" + string(26) "2008-01-29 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/014.phpt b/ext/date/tests/014.phpt index 5e609c8685..3adb32c965 100644 --- a/ext/date/tests/014.phpt +++ b/ext/date/tests/014.phpt @@ -20,7 +20,7 @@ echo "Done\n"; --EXPECTF-- object(DateTime)#%d (3) { ["date"]=> - string(19) "2006-12-12 00:00:00" + string(26) "2006-12-12 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTimeImmutable_createFromMutable.phpt b/ext/date/tests/DateTimeImmutable_createFromMutable.phpt index db893b9821..ac92fb4bb4 100644 --- a/ext/date/tests/DateTimeImmutable_createFromMutable.phpt +++ b/ext/date/tests/DateTimeImmutable_createFromMutable.phpt @@ -15,7 +15,7 @@ var_dump( $i ); --EXPECTF-- object(DateTimeImmutable)#%d (3) { ["date"]=> - string(19) "2014-03-02 16:24:08" + string(26) "2014-03-02 16:24:08.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTime_clone_basic2.phpt b/ext/date/tests/DateTime_clone_basic2.phpt index db7ba22719..99659c10a0 100644 --- a/ext/date/tests/DateTime_clone_basic2.phpt +++ b/ext/date/tests/DateTime_clone_basic2.phpt @@ -37,7 +37,7 @@ object(DateTimeExt1)#%d (5) { ["property2"]=> string(5) "Hello" ["date"]=> - string(19) "2009-02-03 12:34:41" + string(26) "2009-02-03 12:34:41.000000" ["timezone_type"]=> int(2) ["timezone"]=> @@ -49,7 +49,7 @@ object(DateTimeExt1)#%d (5) { ["property2"]=> string(5) "Hello" ["date"]=> - string(19) "2009-02-03 12:34:41" + string(26) "2009-02-03 12:34:41.000000" ["timezone_type"]=> int(2) ["timezone"]=> @@ -65,7 +65,7 @@ object(DateTimeExt2)#%d (7) { ["property2"]=> string(5) "Hello" ["date"]=> - string(19) "2009-02-03 12:34:41" + string(26) "2009-02-03 12:34:41.000000" ["timezone_type"]=> int(2) ["timezone"]=> @@ -81,7 +81,7 @@ object(DateTimeExt2)#%d (7) { ["property2"]=> string(5) "Hello" ["date"]=> - string(19) "2009-02-03 12:34:41" + string(26) "2009-02-03 12:34:41.000000" ["timezone_type"]=> int(2) ["timezone"]=> diff --git a/ext/date/tests/DateTime_clone_basic3.phpt b/ext/date/tests/DateTime_clone_basic3.phpt index 43e289817e..f3d9c142fb 100644 --- a/ext/date/tests/DateTime_clone_basic3.phpt +++ b/ext/date/tests/DateTime_clone_basic3.phpt @@ -32,7 +32,7 @@ var_dump($d2_clone); -- Create a DateTime object -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-02-03 12:34:41" + string(26) "2009-02-03 12:34:41.000000" ["timezone_type"]=> int(2) ["timezone"]=> @@ -42,7 +42,7 @@ object(DateTime)#%d (3) { -- Add some properties -- object(DateTime)#%d (5) { ["date"]=> - string(19) "2009-02-03 12:34:41" + string(26) "2009-02-03 12:34:41.000000" ["timezone_type"]=> int(2) ["timezone"]=> @@ -56,7 +56,7 @@ object(DateTime)#%d (5) { -- clone it -- object(DateTime)#%d (5) { ["date"]=> - string(19) "2009-02-03 12:34:41" + string(26) "2009-02-03 12:34:41.000000" ["timezone_type"]=> int(2) ["timezone"]=> @@ -70,7 +70,7 @@ object(DateTime)#%d (5) { -- Add some more properties -- object(DateTime)#%d (7) { ["date"]=> - string(19) "2009-02-03 12:34:41" + string(26) "2009-02-03 12:34:41.000000" ["timezone_type"]=> int(2) ["timezone"]=> @@ -88,7 +88,7 @@ object(DateTime)#%d (7) { -- clone it -- object(DateTime)#%d (7) { ["date"]=> - string(19) "2009-02-03 12:34:41" + string(26) "2009-02-03 12:34:41.000000" ["timezone_type"]=> int(2) ["timezone"]=> diff --git a/ext/date/tests/DateTime_construct_basic1.phpt b/ext/date/tests/DateTime_construct_basic1.phpt index a865e6bb97..d6a8956bf3 100644 --- a/ext/date/tests/DateTime_construct_basic1.phpt +++ b/ext/date/tests/DateTime_construct_basic1.phpt @@ -41,7 +41,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -49,7 +49,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(2) ["timezone"]=> diff --git a/ext/date/tests/DateTime_construct_variation1.phpt b/ext/date/tests/DateTime_construct_variation1.phpt index d335b5ab1b..f106a40935 100644 --- a/ext/date/tests/DateTime_construct_variation1.phpt +++ b/ext/date/tests/DateTime_construct_variation1.phpt @@ -142,7 +142,7 @@ FAILED: DateTime::__construct(): Failed to parse time string (-12345) at positio -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -150,7 +150,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -164,7 +164,7 @@ FAILED: DateTime::__construct(): Failed to parse time string (-10.5) at position -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -172,7 +172,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -198,7 +198,7 @@ FAILED: DateTime::__construct() expects parameter 1 to be string, array given -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -206,7 +206,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -216,7 +216,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -224,7 +224,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -238,7 +238,7 @@ FAILED: DateTime::__construct(): Failed to parse time string (1) at position 0 ( -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -246,7 +246,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -260,7 +260,7 @@ FAILED: DateTime::__construct(): Failed to parse time string (1) at position 0 ( -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -268,7 +268,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -278,7 +278,7 @@ object(DateTime)#%d (3) { -- empty string DQ -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -286,7 +286,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -296,7 +296,7 @@ object(DateTime)#%d (3) { -- empty string SQ -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -304,7 +304,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -338,7 +338,7 @@ FAILED: DateTime::__construct() expects parameter 1 to be string, object given -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -346,7 +346,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -356,7 +356,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -364,7 +364,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTime_construct_variation2.phpt b/ext/date/tests/DateTime_construct_variation2.phpt index b1d80f9002..dfc1047bc4 100644 --- a/ext/date/tests/DateTime_construct_variation2.phpt +++ b/ext/date/tests/DateTime_construct_variation2.phpt @@ -153,7 +153,7 @@ FAILED: DateTime::__construct() expects parameter 2 to be DateTimeZone, array gi -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -163,7 +163,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -209,7 +209,7 @@ FAILED: DateTime::__construct() expects parameter 2 to be DateTimeZone, object g -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -219,7 +219,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTime_modify_variation1.phpt b/ext/date/tests/DateTime_modify_variation1.phpt index faeb70cbd9..ddb36751ce 100644 --- a/ext/date/tests/DateTime_modify_variation1.phpt +++ b/ext/date/tests/DateTime_modify_variation1.phpt @@ -133,7 +133,7 @@ bool(false) -- float 10.5 -- object(DateTime)#3 (3) { ["date"]=> - string(19) "2009-01-31 10:05:00" + string(26) "2009-01-31 10:05:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -148,7 +148,7 @@ bool(false) -- float .5 -- object(DateTime)#3 (3) { ["date"]=> - string(19) "2009-01-31 00:05:00" + string(26) "2009-01-31 00:05:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTime_serialize.phpt b/ext/date/tests/DateTime_serialize.phpt index ff827360fb..b8af87eee1 100644 --- a/ext/date/tests/DateTime_serialize.phpt +++ b/ext/date/tests/DateTime_serialize.phpt @@ -20,20 +20,20 @@ var_dump( $date2->format( "F j, Y, g:i a") ); --EXPECTF-- object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/London" } -string(118) "O:8:"DateTime":3:{s:4:"date";s:19:"2005-07-14 22:30:41";s:13:"timezone_type";i:3;s:8:"timezone";s:13:"Europe/London";}" +string(125) "O:8:"DateTime":3:{s:4:"date";s:26:"2005-07-14 22:30:41.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:13:"Europe/London";}" object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/London" } string(23) "July 14, 2005, 10:30 pm" -===DONE===
\ No newline at end of file +===DONE=== diff --git a/ext/date/tests/DateTime_setDate_variation1.phpt b/ext/date/tests/DateTime_setDate_variation1.phpt index 5017cc1d78..f5ca4cb727 100644 --- a/ext/date/tests/DateTime_setDate_variation1.phpt +++ b/ext/date/tests/DateTime_setDate_variation1.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-07-02 08:34:10" + string(26) "0000-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-07-02 08:34:10" + string(26) "0001-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(20) "12345-07-02 08:34:10" + string(27) "12345-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(21) "-12345-07-02 08:34:10" + string(28) "-12345-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0010-07-02 08:34:10" + string(26) "0010-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(20) "-0010-07-02 08:34:10" + string(27) "-0010-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-07-02 08:34:10" + string(26) "0000-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-07-02 08:34:10" + string(26) "0000-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-07-02 08:34:10" + string(26) "0000-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-07-02 08:34:10" + string(26) "0001-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-07-02 08:34:10" + string(26) "0000-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-07-02 08:34:10" + string(26) "0001-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-07-02 08:34:10" + string(26) "0000-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-07-02 08:34:10" + string(26) "0000-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-07-02 08:34:10" + string(26) "0000-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -326,4 +326,4 @@ object(DateTime)#%d (3) { Warning: DateTime::setDate() expects parameter 1 to be long, resource given in %s on line %d bool(false) -===DONE===
\ No newline at end of file +===DONE=== diff --git a/ext/date/tests/DateTime_setDate_variation2.phpt b/ext/date/tests/DateTime_setDate_variation2.phpt index a853f5ee2b..ab715c39a6 100644 --- a/ext/date/tests/DateTime_setDate_variation2.phpt +++ b/ext/date/tests/DateTime_setDate_variation2.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-02 08:34:10" + string(26) "1963-01-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2991-09-02 08:34:10" + string(26) "2991-09-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0934-03-02 08:34:10" + string(26) "0934-03-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-10-02 08:34:10" + string(26) "1963-10-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-02-02 08:34:10" + string(26) "1962-02-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-02 08:34:10" + string(26) "1963-01-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-02 08:34:10" + string(26) "1963-01-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTime_setDate_variation3.phpt b/ext/date/tests/DateTime_setDate_variation3.phpt index da98e593fa..8f2e894b1f 100644 --- a/ext/date/tests/DateTime_setDate_variation3.phpt +++ b/ext/date/tests/DateTime_setDate_variation3.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-07-01 08:34:10" + string(26) "1963-07-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1997-04-17 08:34:10" + string(26) "1997-04-17 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1929-09-11 08:34:10" + string(26) "1929-09-11 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-07-10 08:34:10" + string(26) "1963-07-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-20 08:34:10" + string(26) "1963-06-20 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-07-01 08:34:10" + string(26) "1963-07-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-07-01 08:34:10" + string(26) "1963-07-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTime_setISODate_variation1.phpt b/ext/date/tests/DateTime_setISODate_variation1.phpt index ded968fa8f..d685f27ed0 100644 --- a/ext/date/tests/DateTime_setISODate_variation1.phpt +++ b/ext/date/tests/DateTime_setISODate_variation1.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-02-13 08:34:10" + string(26) "0001-02-13 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(20) "12345-02-13 08:34:10" + string(27) "12345-02-13 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(21) "-12345-02-15 08:34:10" + string(28) "-12345-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0010-02-16 08:34:10" + string(26) "0010-02-16 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(20) "-0010-02-19 08:34:10" + string(27) "-0010-02-19 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-02-13 08:34:10" + string(26) "0001-02-13 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-02-13 08:34:10" + string(26) "0001-02-13 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTime_setISODate_variation2.phpt b/ext/date/tests/DateTime_setISODate_variation2.phpt index ce322d2530..496e1c91f6 100644 --- a/ext/date/tests/DateTime_setISODate_variation2.phpt +++ b/ext/date/tests/DateTime_setISODate_variation2.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-01 08:34:10" + string(26) "1963-01-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2199-07-30 08:34:10" + string(26) "2199-07-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1726-05-21 08:34:10" + string(26) "1726-05-21 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-03-05 08:34:10" + string(26) "1963-03-05 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-10-16 08:34:10" + string(26) "1962-10-16 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-01 08:34:10" + string(26) "1963-01-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-01 08:34:10" + string(26) "1963-01-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTime_setISODate_variation3.phpt b/ext/date/tests/DateTime_setISODate_variation3.phpt index d2d5644fbf..5b69b2faad 100644 --- a/ext/date/tests/DateTime_setISODate_variation3.phpt +++ b/ext/date/tests/DateTime_setISODate_variation3.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-11 08:34:10" + string(26) "1963-02-11 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1996-11-28 08:34:10" + string(26) "1996-11-28 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1929-04-24 08:34:10" + string(26) "1929-04-24 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-20 08:34:10" + string(26) "1963-02-20 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-31 08:34:10" + string(26) "1963-01-31 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-11 08:34:10" + string(26) "1963-02-11 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-11 08:34:10" + string(26) "1963-02-11 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTime_setTime_variation1.phpt b/ext/date/tests/DateTime_setTime_variation1.phpt index 7edbd4ea47..1805081912 100644 --- a/ext/date/tests/DateTime_setTime_variation1.phpt +++ b/ext/date/tests/DateTime_setTime_variation1.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 00:13:45" + string(26) "2009-01-31 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 01:13:45" + string(26) "2009-01-31 01:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2010-06-29 09:13:45" + string(26) "2010-06-29 09:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 15:13:45" + string(26) "2009-01-30 15:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:13:45" + string(26) "2009-01-30 10:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 14:13:45" + string(26) "2009-01-29 14:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 01:13:45" + string(26) "2009-01-29 01:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 01:13:45" + string(26) "2009-01-29 01:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTime_setTime_variation2.phpt b/ext/date/tests/DateTime_setTime_variation2.phpt index 300eb9c001..fc034bf212 100644 --- a/ext/date/tests/DateTime_setTime_variation2.phpt +++ b/ext/date/tests/DateTime_setTime_variation2.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:00:45" + string(26) "2009-01-31 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:01:45" + string(26) "2009-01-31 10:01:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-02-08 23:45:45" + string(26) "2009-02-08 23:45:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 20:15:45" + string(26) "2009-01-30 20:15:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:10:45" + string(26) "2009-01-30 10:10:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 09:50:45" + string(26) "2009-01-30 09:50:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:01:45" + string(26) "2009-01-30 10:01:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:01:45" + string(26) "2009-01-30 10:01:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/DateTime_setTime_variation3.phpt b/ext/date/tests/DateTime_setTime_variation3.phpt index 05bf4b5e52..21c62e0012 100644 --- a/ext/date/tests/DateTime_setTime_variation3.phpt +++ b/ext/date/tests/DateTime_setTime_variation3.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:01" + string(26) "2009-01-31 10:13:01.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 13:38:45" + string(26) "2009-01-31 13:38:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 06:47:15" + string(26) "2009-01-31 06:47:15.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:10" + string(26) "2009-01-31 10:13:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:12:50" + string(26) "2009-01-31 10:12:50.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:01" + string(26) "2009-01-31 10:13:01.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:01" + string(26) "2009-01-31 10:13:01.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/bug41523-64bit.phpt b/ext/date/tests/bug41523-64bit.phpt index d6d1320034..0c0e8076c3 100644 --- a/ext/date/tests/bug41523-64bit.phpt +++ b/ext/date/tests/bug41523-64bit.phpt @@ -46,7 +46,7 @@ array(12) { int(-62169984000) object(DateTime)#1 (3) { ["date"]=> - string(20) "-0001-11-30 00:00:00" + string(27) "-0001-11-30 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/bug41523.phpt b/ext/date/tests/bug41523.phpt index 948dae7dbf..68fe1bd6a3 100644 --- a/ext/date/tests/bug41523.phpt +++ b/ext/date/tests/bug41523.phpt @@ -46,7 +46,7 @@ array(12) { bool(false) object(DateTime)#1 (3) { ["date"]=> - string(20) "-0001-11-30 00:00:00" + string(27) "-0001-11-30 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/bug48097.phpt b/ext/date/tests/bug48097.phpt index d71a97e5a6..41ade81247 100644 --- a/ext/date/tests/bug48097.phpt +++ b/ext/date/tests/bug48097.phpt @@ -16,7 +16,7 @@ echo $d->format( 'U' ), "\n\n"; --EXPECT-- object(DateTime)#1 (3) { ["date"]=> - string(19) "1955-05-23 00:00:00" + string(26) "1955-05-23 00:00:00.000000" ["timezone_type"]=> int(1) ["timezone"]=> @@ -27,7 +27,7 @@ object(DateTime)#1 (3) { object(DateTime)#1 (3) { ["date"]=> - string(19) "1955-05-22 23:00:00" + string(26) "1955-05-22 23:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/bug51866.phpt b/ext/date/tests/bug51866.phpt index 8d765b02f0..9474f4f58d 100644 --- a/ext/date/tests/bug51866.phpt +++ b/ext/date/tests/bug51866.phpt @@ -46,7 +46,7 @@ string(6) "Y-m-d+" string(19) "2001-11-29 13:20:01" object(DateTime)#2 (3) { ["date"]=> - string(19) "2001-11-29 %d:%d:%d" + string(26) "2001-11-29 %d:%d:%d.%d" ["timezone_type"]=> int(3) ["timezone"]=> @@ -72,7 +72,7 @@ string(7) "Y-m-d +" string(19) "2001-11-29 13:20:01" object(DateTime)#3 (3) { ["date"]=> - string(19) "2001-11-29 %d:%d:%d" + string(26) "2001-11-29 %d:%d:%d.%d" ["timezone_type"]=> int(3) ["timezone"]=> @@ -98,7 +98,7 @@ string(6) "Y-m-d+" string(10) "2001-11-29" object(DateTime)#2 (3) { ["date"]=> - string(19) "2001-11-29 %d:%d:%d" + string(26) "2001-11-29 %d:%d:%d.%d" ["timezone_type"]=> int(3) ["timezone"]=> @@ -141,7 +141,7 @@ string(7) "Y-m-d +" string(11) "2001-11-29 " object(DateTime)#2 (3) { ["date"]=> - string(19) "2001-11-29 %d:%d:%d" + string(26) "2001-11-29 %d:%d:%d.%d" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/bug52113.phpt b/ext/date/tests/bug52113.phpt index f4730c6a44..62c2fca94e 100644 --- a/ext/date/tests/bug52113.phpt +++ b/ext/date/tests/bug52113.phpt @@ -117,7 +117,7 @@ object(DatePeriod)#6 (6) { ["start"]=> object(DateTime)#4 (3) { ["date"]=> - string(19) "2003-01-02 08:00:00" + string(26) "2003-01-02 08:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -201,7 +201,7 @@ object(DatePeriod)#9 (6) { ["start"]=> object(DateTime)#6 (3) { ["date"]=> - string(19) "2003-01-02 08:00:00" + string(26) "2003-01-02 08:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/bug53437.phpt b/ext/date/tests/bug53437.phpt index 2ea091453f..f82a4879b3 100644 --- a/ext/date/tests/bug53437.phpt +++ b/ext/date/tests/bug53437.phpt @@ -33,7 +33,7 @@ object(DatePeriod)#1 (6) { ["start"]=> object(DateTime)#2 (3) { ["date"]=> - string(19) "2010-01-01 00:00:00" + string(26) "2010-01-01 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -42,7 +42,7 @@ object(DatePeriod)#1 (6) { ["current"]=> object(DateTime)#4 (3) { ["date"]=> - string(19) "2010-01-04 00:00:00" + string(26) "2010-01-04 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -92,7 +92,7 @@ object(DatePeriod)#5 (6) { ["start"]=> object(DateTime)#10 (3) { ["date"]=> - string(19) "2010-01-01 00:00:00" + string(26) "2010-01-01 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -101,7 +101,7 @@ object(DatePeriod)#5 (6) { ["current"]=> object(DateTime)#7 (3) { ["date"]=> - string(19) "2010-01-04 00:00:00" + string(26) "2010-01-04 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/bug53879.phpt b/ext/date/tests/bug53879.phpt index 3d16c97209..3fd8250415 100644 --- a/ext/date/tests/bug53879.phpt +++ b/ext/date/tests/bug53879.phpt @@ -10,7 +10,7 @@ print_r($date); --EXPECTF-- DateTime Object ( - [date] => 2041-01-21 15:24:52 + [date] => 2041-01-21 15:24:52.000000 [timezone_type] => 2 [timezone] => GMT ) diff --git a/ext/date/tests/bug54316.phpt b/ext/date/tests/bug54316.phpt index a02288cdba..21afa637d8 100644 --- a/ext/date/tests/bug54316.phpt +++ b/ext/date/tests/bug54316.phpt @@ -12,7 +12,7 @@ var_dump($dt); --EXPECT-- object(DateTime)#1 (3) { ["date"]=> - string(19) "2011-02-02 00:00:00" + string(26) "2011-02-02 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -20,7 +20,7 @@ object(DateTime)#1 (3) { } object(DateTime)#2 (3) { ["date"]=> - string(19) "1970-01-01 00:00:00" + string(26) "1970-01-01 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/bug54340.phpt b/ext/date/tests/bug54340.phpt index 7f00309c93..eb977c35ee 100644 --- a/ext/date/tests/bug54340.phpt +++ b/ext/date/tests/bug54340.phpt @@ -19,7 +19,7 @@ var_dump($dt); --EXPECT-- object(DateTime)#2 (3) { ["date"]=> - string(19) "2011-01-01 00:00:00" + string(26) "2011-01-01 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -27,7 +27,7 @@ object(DateTime)#2 (3) { } object(DateTime)#2 (3) { ["date"]=> - string(19) "2011-01-02 00:00:00" + string(26) "2011-01-02 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -35,7 +35,7 @@ object(DateTime)#2 (3) { } object(DateTime)#3 (3) { ["date"]=> - string(19) "2010-12-31 00:00:00" + string(26) "2010-12-31 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/bug60236.phpt b/ext/date/tests/bug60236.phpt index faa0e160ce..a71bb5a17d 100644 --- a/ext/date/tests/bug60236.phpt +++ b/ext/date/tests/bug60236.phpt @@ -14,7 +14,7 @@ var_dump($t); string(10) "1278455908" object(DateTime)#1 (3) { ["date"]=> - string(19) "2010-07-06 18:38:28" + string(26) "2010-07-06 18:38:28.000000" ["timezone_type"]=> int(2) ["timezone"]=> diff --git a/ext/date/tests/bug67118.phpt b/ext/date/tests/bug67118.phpt new file mode 100644 index 0000000000..19b5914aa3 --- /dev/null +++ b/ext/date/tests/bug67118.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #67118 crashes in DateTime when this used after failed __construct +--INI-- +date.timezone=Europe/Berlin +--FILE-- +<?php +class mydt extends datetime +{ + public function __construct($time = 'now', $tz = NULL, $format = NULL) + { + if (!empty($tz) && !is_object($tz)) { + $tz = new DateTimeZone($tz); + } + try { + @parent::__construct($time, $tz); + } catch (Exception $e) { + echo "Bad date" . $this->format("Y") . "\n"; + } + } + +}; + +new mydt("Funktionsansvarig rådgivning och juridik", "UTC"); +?> +--EXPECTF-- +Fatal error: Call to a member function format() on null in %sbug67118.php on line %d diff --git a/ext/date/tests/bug67118_2.phpt b/ext/date/tests/bug67118_2.phpt new file mode 100644 index 0000000000..368d4d9401 --- /dev/null +++ b/ext/date/tests/bug67118_2.phpt @@ -0,0 +1,28 @@ +--TEST-- +Regression introduce in fix for Bug #67118 - Invalid code +--INI-- +date.timezone=Europe/Paris +--FILE-- +<?php +class Foo extends DateTime { + public function __construct($time = null) { + $tz = new DateTimeZone('UTC'); + try { + echo "First try\n"; + parent::__construct($time, $tz); + return; + } catch (Exception $e) { + echo "Second try\n"; + parent::__construct($time.'C', $tz); + } + } +} +$date = '12 Sep 2007 15:49:12 UT'; +var_dump(new Foo($date)); +?> +Done +--EXPECTF-- +First try +Second try +NULL +Done
\ No newline at end of file diff --git a/ext/date/tests/bug67251.phpt b/ext/date/tests/bug67251.phpt new file mode 100644 index 0000000000..68c56a1613 --- /dev/null +++ b/ext/date/tests/bug67251.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #67251 (date_parse_from_format out-of-bounds read) +--INI-- +date.timezone=Europe/Berlin +--FILE-- +<?php +var_dump(date_parse_from_format("\\","AAAABBBB")); +--EXPECT-- +array(12) { + ["year"]=> + bool(false) + ["month"]=> + bool(false) + ["day"]=> + bool(false) + ["hour"]=> + bool(false) + ["minute"]=> + bool(false) + ["second"]=> + bool(false) + ["fraction"]=> + bool(false) + ["warning_count"]=> + int(0) + ["warnings"]=> + array(0) { + } + ["error_count"]=> + int(2) + ["errors"]=> + array(1) { + [0]=> + string(13) "Trailing data" + } + ["is_localtime"]=> + bool(false) +} diff --git a/ext/date/tests/bug67253.phpt b/ext/date/tests/bug67253.phpt new file mode 100644 index 0000000000..b28cbe63c1 --- /dev/null +++ b/ext/date/tests/bug67253.phpt @@ -0,0 +1,44 @@ +--TEST-- +Bug #67253 (timelib_meridian_with_check out-of-bounds read) +--INI-- +date.timezone=Europe/Berlin +--FILE-- +<?php +$z = ''; +var_dump(date_parse_from_format("aHa0", "0=G{$z}9UCNnF")); +--EXPECT-- +array(12) { + ["year"]=> + bool(false) + ["month"]=> + bool(false) + ["day"]=> + bool(false) + ["hour"]=> + int(0) + ["minute"]=> + int(0) + ["second"]=> + int(0) + ["fraction"]=> + bool(false) + ["warning_count"]=> + int(0) + ["warnings"]=> + array(0) { + } + ["error_count"]=> + int(3) + ["errors"]=> + array(3) { + [0]=> + string(51) "Meridian can only come after an hour has been found" + [1]=> + string(29) "A meridian could not be found" + [9]=> + string(12) "Data missing" + } + ["is_localtime"]=> + bool(false) +} + diff --git a/ext/date/tests/bug67308.phpt b/ext/date/tests/bug67308.phpt new file mode 100644 index 0000000000..39fb781884 --- /dev/null +++ b/ext/date/tests/bug67308.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #67308 (Serialize of DateTime truncates fractions of second) +--INI-- +date.timezone=America/Vancouver +--FILE-- +<?php +// Ensure we can still unserialize the old style. +var_dump(unserialize('O:8:"DateTime":3:{s:4:"date";s:19:"2005-07-14 22:30:41";s:13:"timezone_type";i:3;s:8:"timezone";s:13:"Europe/London";}')); + +// New style. +var_dump(unserialize('O:8:"DateTime":3:{s:4:"date";s:26:"2005-07-14 22:30:41.123456";s:13:"timezone_type";i:3;s:8:"timezone";s:13:"Europe/London";}')); +--EXPECTF-- +object(DateTime)#%d (3) { + ["date"]=> + string(26) "2005-07-14 22:30:41.000000" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(13) "Europe/London" +} +object(DateTime)#%d (3) { + ["date"]=> + string(26) "2005-07-14 22:30:41.123456" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(13) "Europe/London" +} diff --git a/ext/date/tests/date-lenient-create.phpt b/ext/date/tests/date-lenient-create.phpt index 49ee3c1371..2d59ceba79 100644 --- a/ext/date/tests/date-lenient-create.phpt +++ b/ext/date/tests/date-lenient-create.phpt @@ -46,7 +46,7 @@ Array == DateTime Object ( - [date] => 2004-06-08 00:00:00 + [date] => 2004-06-08 00:00:00.000000 [timezone_type] => 3 [timezone] => UTC ) @@ -67,7 +67,7 @@ Array == DateTime Object ( - [date] => 2004-06-08 00:00:00 + [date] => 2004-06-08 00:00:00.000000 [timezone_type] => 3 [timezone] => UTC ) @@ -88,7 +88,7 @@ Array == DateTime Object ( - [date] => 2004-06-08 00:00:00 + [date] => 2004-06-08 00:00:00.000000 [timezone_type] => 3 [timezone] => UTC ) @@ -109,7 +109,7 @@ Array == DateTime Object ( - [date] => 2004-06-08 00:00:00 + [date] => 2004-06-08 00:00:00.000000 [timezone_type] => 3 [timezone] => UTC ) @@ -129,7 +129,7 @@ Array == DateTime Object ( - [date] => 2004-06-08 00:00:00 + [date] => 2004-06-08 00:00:00.000000 [timezone_type] => 3 [timezone] => UTC ) diff --git a/ext/date/tests/date_create_basic.phpt b/ext/date/tests/date_create_basic.phpt index edec80bda1..4e13afebb3 100644 --- a/ext/date/tests/date_create_basic.phpt +++ b/ext/date/tests/date_create_basic.phpt @@ -25,7 +25,7 @@ var_dump( date_create("2005-07-14 22:30:41 GMT") ); *** Testing date_create() : basic functionality *** object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -33,7 +33,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(2) ["timezone"]=> @@ -41,7 +41,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -49,10 +49,10 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(2) ["timezone"]=> string(3) "GMT" } -===DONE===
\ No newline at end of file +===DONE=== diff --git a/ext/date/tests/date_create_variation1.phpt b/ext/date/tests/date_create_variation1.phpt index f5fb2fd912..a476473a10 100644 --- a/ext/date/tests/date_create_variation1.phpt +++ b/ext/date/tests/date_create_variation1.phpt @@ -130,7 +130,7 @@ bool(false) -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -138,7 +138,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -152,7 +152,7 @@ bool(false) -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -160,7 +160,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -202,7 +202,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -210,7 +210,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -220,7 +220,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -228,7 +228,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -242,7 +242,7 @@ bool(false) -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -250,7 +250,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -264,7 +264,7 @@ bool(false) -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -272,7 +272,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -282,7 +282,7 @@ object(DateTime)#%d (3) { -- empty string DQ -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -290,7 +290,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -300,7 +300,7 @@ object(DateTime)#%d (3) { -- empty string SQ -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -308,7 +308,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -346,7 +346,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -354,7 +354,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -364,7 +364,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> @@ -372,7 +372,7 @@ object(DateTime)#%d (3) { } object(DateTime)#%d (3) { ["date"]=> - string(19) "%s" + string(26) "%s" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/date_create_variation2.phpt b/ext/date/tests/date_create_variation2.phpt index c43ccb0699..ad5d0e8705 100644 --- a/ext/date/tests/date_create_variation2.phpt +++ b/ext/date/tests/date_create_variation2.phpt @@ -168,7 +168,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -178,7 +178,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -248,7 +248,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -258,7 +258,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2005-07-14 22:30:41" + string(26) "2005-07-14 22:30:41.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/date_date_set_variation2.phpt b/ext/date/tests/date_date_set_variation2.phpt index 384885c6fc..85bfc5e82d 100644 --- a/ext/date/tests/date_date_set_variation2.phpt +++ b/ext/date/tests/date_date_set_variation2.phpt @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-07-02 08:34:10" + string(26) "0001-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(20) "12345-07-02 08:34:10" + string(27) "12345-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(21) "-12345-07-02 08:34:10" + string(28) "-12345-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0010-07-02 08:34:10" + string(26) "0010-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(20) "-0010-07-02 08:34:10" + string(27) "-0010-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-07-02 08:34:10" + string(26) "0001-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-07-02 08:34:10" + string(26) "0001-07-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/date_date_set_variation3.phpt b/ext/date/tests/date_date_set_variation3.phpt index 80703414be..2cca53d651 100644 --- a/ext/date/tests/date_date_set_variation3.phpt +++ b/ext/date/tests/date_date_set_variation3.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-02 08:34:10" + string(26) "1963-01-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2991-09-02 08:34:10" + string(26) "2991-09-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0934-03-02 08:34:10" + string(26) "0934-03-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-10-02 08:34:10" + string(26) "1963-10-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-02-02 08:34:10" + string(26) "1962-02-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-02 08:34:10" + string(26) "1963-01-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-02 08:34:10" + string(26) "1963-01-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-02 08:34:10" + string(26) "1962-12-02 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/date_date_set_variation4.phpt b/ext/date/tests/date_date_set_variation4.phpt index 4c7df3d33b..f87988e51e 100644 --- a/ext/date/tests/date_date_set_variation4.phpt +++ b/ext/date/tests/date_date_set_variation4.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-07-01 08:34:10" + string(26) "1963-07-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1997-04-17 08:34:10" + string(26) "1997-04-17 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1929-09-11 08:34:10" + string(26) "1929-09-11 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-07-10 08:34:10" + string(26) "1963-07-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-20 08:34:10" + string(26) "1963-06-20 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-07-01 08:34:10" + string(26) "1963-07-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-07-01 08:34:10" + string(26) "1963-07-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-06-30 08:34:10" + string(26) "1963-06-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/date_diff1.phpt b/ext/date/tests/date_diff1.phpt index a908cdba75..fefffcde52 100644 --- a/ext/date/tests/date_diff1.phpt +++ b/ext/date/tests/date_diff1.phpt @@ -14,7 +14,7 @@ var_dump($int); --EXPECT-- object(DateTime)#1 (3) { ["date"]=> - string(19) "2010-10-04 02:18:48" + string(26) "2010-10-04 02:18:48.000000" ["timezone_type"]=> int(2) ["timezone"]=> @@ -22,7 +22,7 @@ object(DateTime)#1 (3) { } object(DateTime)#2 (3) { ["date"]=> - string(19) "2010-11-06 18:38:28" + string(26) "2010-11-06 18:38:28.000000" ["timezone_type"]=> int(2) ["timezone"]=> diff --git a/ext/date/tests/date_isodate_set_variation2.phpt b/ext/date/tests/date_isodate_set_variation2.phpt index fa42a95814..5b59a696c6 100644 --- a/ext/date/tests/date_isodate_set_variation2.phpt +++ b/ext/date/tests/date_isodate_set_variation2.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-02-13 08:34:10" + string(26) "0001-02-13 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(20) "12345-02-13 08:34:10" + string(27) "12345-02-13 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(21) "-12345-02-15 08:34:10" + string(28) "-12345-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0010-02-16 08:34:10" + string(26) "0010-02-16 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(20) "-0010-02-19 08:34:10" + string(27) "-0010-02-19 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-02-13 08:34:10" + string(26) "0001-02-13 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0001-02-13 08:34:10" + string(26) "0001-02-13 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "0000-02-15 08:34:10" + string(26) "0000-02-15 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/date_isodate_set_variation3.phpt b/ext/date/tests/date_isodate_set_variation3.phpt index eeb8471e2c..52c2348fe3 100644 --- a/ext/date/tests/date_isodate_set_variation3.phpt +++ b/ext/date/tests/date_isodate_set_variation3.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-01 08:34:10" + string(26) "1963-01-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2199-07-30 08:34:10" + string(26) "2199-07-30 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1726-05-21 08:34:10" + string(26) "1726-05-21 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-03-05 08:34:10" + string(26) "1963-03-05 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-10-16 08:34:10" + string(26) "1962-10-16 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-01 08:34:10" + string(26) "1963-01-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-01 08:34:10" + string(26) "1963-01-01 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1962-12-25 08:34:10" + string(26) "1962-12-25 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/date_isodate_set_variation4.phpt b/ext/date/tests/date_isodate_set_variation4.phpt index 5da3c038e3..b223f39b69 100644 --- a/ext/date/tests/date_isodate_set_variation4.phpt +++ b/ext/date/tests/date_isodate_set_variation4.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-11 08:34:10" + string(26) "1963-02-11 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1996-11-28 08:34:10" + string(26) "1996-11-28 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1929-04-24 08:34:10" + string(26) "1929-04-24 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-20 08:34:10" + string(26) "1963-02-20 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-01-31 08:34:10" + string(26) "1963-01-31 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-11 08:34:10" + string(26) "1963-02-11 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-11 08:34:10" + string(26) "1963-02-11 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "1963-02-10 08:34:10" + string(26) "1963-02-10 08:34:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/date_modify_variation2.phpt b/ext/date/tests/date_modify_variation2.phpt index fe6afb16dd..a28261be44 100644 --- a/ext/date/tests/date_modify_variation2.phpt +++ b/ext/date/tests/date_modify_variation2.phpt @@ -133,7 +133,7 @@ bool(false) -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:05:00" + string(26) "2009-01-31 10:05:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -148,7 +148,7 @@ bool(false) -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 00:05:00" + string(26) "2009-01-31 00:05:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/date_time_set_variation2.phpt b/ext/date/tests/date_time_set_variation2.phpt index e8a6d7ef9e..c19650c161 100644 --- a/ext/date/tests/date_time_set_variation2.phpt +++ b/ext/date/tests/date_time_set_variation2.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 00:13:45" + string(26) "2009-01-31 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 01:13:45" + string(26) "2009-01-31 01:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2010-06-29 09:13:45" + string(26) "2010-06-29 09:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 15:13:45" + string(26) "2009-01-30 15:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:13:45" + string(26) "2009-01-30 10:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 14:13:45" + string(26) "2009-01-29 14:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 01:13:45" + string(26) "2009-01-29 01:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 01:13:45" + string(26) "2009-01-29 01:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-29 00:13:45" + string(26) "2009-01-29 00:13:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/date_time_set_variation3.phpt b/ext/date/tests/date_time_set_variation3.phpt index 9be25b5923..0ad04c8a66 100644 --- a/ext/date/tests/date_time_set_variation3.phpt +++ b/ext/date/tests/date_time_set_variation3.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#3 (3) { ["date"]=> - string(19) "2009-01-31 10:00:45" + string(26) "2009-01-31 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#3 (3) { -- int 1 -- object(DateTime)#3 (3) { ["date"]=> - string(19) "2009-01-31 10:01:45" + string(26) "2009-01-31 10:01:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#3 (3) { -- int 12345 -- object(DateTime)#3 (3) { ["date"]=> - string(19) "2009-02-08 23:45:45" + string(26) "2009-02-08 23:45:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#3 (3) { -- int -12345 -- object(DateTime)#3 (3) { ["date"]=> - string(19) "2009-01-30 20:15:45" + string(26) "2009-01-30 20:15:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#3 (3) { -- float 10.5 -- object(DateTime)#3 (3) { ["date"]=> - string(19) "2009-01-30 10:10:45" + string(26) "2009-01-30 10:10:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#3 (3) { -- float -10.5 -- object(DateTime)#3 (3) { ["date"]=> - string(19) "2009-01-30 09:50:45" + string(26) "2009-01-30 09:50:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#3 (3) { -- float .5 -- object(DateTime)#3 (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:01:45" + string(26) "2009-01-30 10:01:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:01:45" + string(26) "2009-01-30 10:01:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-30 10:00:45" + string(26) "2009-01-30 10:00:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -326,4 +326,4 @@ object(DateTime)#%d (3) { Warning: date_time_set() expects parameter 3 to be long, resource given in %s on line %d bool(false) -===DONE===
\ No newline at end of file +===DONE=== diff --git a/ext/date/tests/date_time_set_variation4.phpt b/ext/date/tests/date_time_set_variation4.phpt index 1da497b85e..8e6fbfb606 100644 --- a/ext/date/tests/date_time_set_variation4.phpt +++ b/ext/date/tests/date_time_set_variation4.phpt @@ -115,7 +115,7 @@ fclose( $file_handle ); -- int 0 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -125,7 +125,7 @@ object(DateTime)#%d (3) { -- int 1 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:01" + string(26) "2009-01-31 10:13:01.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -135,7 +135,7 @@ object(DateTime)#%d (3) { -- int 12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 13:38:45" + string(26) "2009-01-31 13:38:45.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -145,7 +145,7 @@ object(DateTime)#%d (3) { -- int -12345 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 06:47:15" + string(26) "2009-01-31 06:47:15.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -155,7 +155,7 @@ object(DateTime)#%d (3) { -- float 10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:10" + string(26) "2009-01-31 10:13:10.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -165,7 +165,7 @@ object(DateTime)#%d (3) { -- float -10.5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:12:50" + string(26) "2009-01-31 10:12:50.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -175,7 +175,7 @@ object(DateTime)#%d (3) { -- float .5 -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -205,7 +205,7 @@ bool(false) -- uppercase NULL -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -215,7 +215,7 @@ object(DateTime)#%d (3) { -- lowercase null -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -225,7 +225,7 @@ object(DateTime)#%d (3) { -- lowercase true -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:01" + string(26) "2009-01-31 10:13:01.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -235,7 +235,7 @@ object(DateTime)#%d (3) { -- lowercase false -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -245,7 +245,7 @@ object(DateTime)#%d (3) { -- uppercase TRUE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:01" + string(26) "2009-01-31 10:13:01.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -255,7 +255,7 @@ object(DateTime)#%d (3) { -- uppercase FALSE -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -305,7 +305,7 @@ bool(false) -- undefined var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> @@ -315,7 +315,7 @@ object(DateTime)#%d (3) { -- unset var -- object(DateTime)#%d (3) { ["date"]=> - string(19) "2009-01-31 10:13:00" + string(26) "2009-01-31 10:13:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/test-parse-from-format.phpt b/ext/date/tests/test-parse-from-format.phpt index 5bb5fe5325..ee0bd68d6b 100644 --- a/ext/date/tests/test-parse-from-format.phpt +++ b/ext/date/tests/test-parse-from-format.phpt @@ -25,7 +25,7 @@ string(13) "Y-m-d\TH:i:sP" string(25) "2008-07-08T22:14:12+02:00" object(DateTime)#2 (3) { ["date"]=> - string(19) "2008-07-08 22:14:12" + string(26) "2008-07-08 22:14:12.000000" ["timezone_type"]=> int(1) ["timezone"]=> @@ -36,7 +36,7 @@ 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" + string(26) "2008-07-08 22:14:12.000000" ["timezone_type"]=> int(1) ["timezone"]=> @@ -47,7 +47,7 @@ string(13) "Y-m-d\TH:i:sO" string(24) "2008-07-08T22:14:12+0200" object(DateTime)#3 (3) { ["date"]=> - string(19) "2008-07-08 22:14:12" + string(26) "2008-07-08 22:14:12.000000" ["timezone_type"]=> int(1) ["timezone"]=> @@ -58,7 +58,7 @@ string(16) "D, d M y H:i:s O" string(29) "Tue, 08 Jul 08 22:14:12 +0200" object(DateTime)#2 (3) { ["date"]=> - string(19) "2008-07-08 22:14:12" + string(26) "2008-07-08 22:14:12.000000" ["timezone_type"]=> int(1) ["timezone"]=> @@ -69,7 +69,7 @@ string(16) "l, d-M-y H:i:s T" string(36) "Tuesday, 08-Jul-08 22:14:12 GMT+0200" object(DateTime)#1 (3) { ["date"]=> - string(19) "2008-07-08 22:14:12" + string(26) "2008-07-08 22:14:12.000000" ["timezone_type"]=> int(1) ["timezone"]=> @@ -80,7 +80,7 @@ string(16) "D, d M y H:i:s O" string(29) "Tue, 08 Jul 08 22:14:12 +0200" object(DateTime)#3 (3) { ["date"]=> - string(19) "2008-07-08 22:14:12" + string(26) "2008-07-08 22:14:12.000000" ["timezone_type"]=> int(1) ["timezone"]=> @@ -91,7 +91,7 @@ string(16) "D, d M Y H:i:s O" string(31) "Tue, 08 Jul 2008 22:14:12 +0200" object(DateTime)#2 (3) { ["date"]=> - string(19) "2008-07-08 22:14:12" + string(26) "2008-07-08 22:14:12.000000" ["timezone_type"]=> int(1) ["timezone"]=> @@ -102,7 +102,7 @@ string(16) "D, d M Y H:i:s O" string(31) "Tue, 08 Jul 2008 22:14:12 +0200" object(DateTime)#1 (3) { ["date"]=> - string(19) "2008-07-08 22:14:12" + string(26) "2008-07-08 22:14:12.000000" ["timezone_type"]=> int(1) ["timezone"]=> @@ -113,7 +113,7 @@ string(13) "Y-m-d\TH:i:sP" string(25) "2008-07-08T22:14:12+02:00" object(DateTime)#3 (3) { ["date"]=> - string(19) "2008-07-08 22:14:12" + string(26) "2008-07-08 22:14:12.000000" ["timezone_type"]=> int(1) ["timezone"]=> @@ -124,7 +124,7 @@ string(16) "D, d M Y H:i:s O" string(31) "Tue, 08 Jul 2008 22:14:12 +0200" object(DateTime)#2 (3) { ["date"]=> - string(19) "2008-07-08 22:14:12" + string(26) "2008-07-08 22:14:12.000000" ["timezone_type"]=> int(1) ["timezone"]=> @@ -135,7 +135,7 @@ string(13) "Y-m-d\TH:i:sP" string(25) "2008-07-08T22:14:12+02:00" object(DateTime)#1 (3) { ["date"]=> - string(19) "2008-07-08 22:14:12" + string(26) "2008-07-08 22:14:12.000000" ["timezone_type"]=> int(1) ["timezone"]=> diff --git a/ext/dom/tests/DOMDocument_validate_external_dtd.phpt b/ext/dom/tests/DOMDocument_validate_external_dtd.phpt index 51a044c54a..dd4ec960d2 100644 --- a/ext/dom/tests/DOMDocument_validate_external_dtd.phpt +++ b/ext/dom/tests/DOMDocument_validate_external_dtd.phpt @@ -12,6 +12,7 @@ require_once dirname(__FILE__) .'/skipif.inc'; // reusing existing xml: http://cvs.php.net/viewvc.cgi/php-src/ext/dom/tests/dom.xml?view=co&content-type=text%2Fplain // reusing existing dtd: http://cvs.php.net/viewvc.cgi/php-src/ext/dom/tests/dom.ent?view=co&content-type=text%2Fplain $dom = new DOMDocument('1.0'); +$dom->substituteEntities = true; $dom->load(dirname(__FILE__).'/dom.xml'); var_dump($dom->validate()); ?> diff --git a/ext/dom/tests/bug67081.phpt b/ext/dom/tests/bug67081.phpt index 56c2c8e58b..c6dc007d43 100644 --- a/ext/dom/tests/bug67081.phpt +++ b/ext/dom/tests/bug67081.phpt @@ -7,18 +7,22 @@ require_once('skipif.inc'); --FILE-- <?php $domDocument = new DOMDocument(); + $domDocument->substituteEntities = true; $domDocument->load(dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug67081_0.xml"); var_dump($domDocument->doctype->internalSubset); $domDocument = new DOMDocument(); + $domDocument->substituteEntities = true; $domDocument->load(dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug67081_1.xml"); var_dump($domDocument->doctype->internalSubset); $domDocument = new DOMDocument(); + $domDocument->substituteEntities = true; $domDocument->load(dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug67081_2.xml"); var_dump($domDocument->doctype->internalSubset); $domDocument = new DOMDocument(); + $domDocument->substituteEntities = true; $domDocument->load(dirname(__FILE__) . DIRECTORY_SEPARATOR . "dom.xml"); var_dump($domDocument->doctype->internalSubset); ?> diff --git a/ext/exif/tests/exif004.phpt b/ext/exif/tests/exif004.phpt index 229f49e145..8797955f8c 100644 --- a/ext/exif/tests/exif004.phpt +++ b/ext/exif/tests/exif004.phpt @@ -18,7 +18,7 @@ exif.encode_unicode=ISO-8859-1 test4.jpg is a 1*1 image that contains Exif tags written by WindowsXP */ $image = exif_read_data(dirname(__FILE__).'/test4.jpg','',true,false); -echo var_dump($image['WINXP']); +var_dump($image['WINXP']); ?> --EXPECT-- array(5) { diff --git a/ext/ext_skel b/ext/ext_skel index 061e78d649..e6b01fd4fc 100755 --- a/ext/ext_skel +++ b/ext/ext_skel @@ -320,7 +320,7 @@ To use your new extension, you will have to execute the following steps: 3. $ ./buildconf 4. $ ./configure --[with|enable]-$extname 5. $ make -6. $ ./php -f ext/$extname/$extname.php +6. $ ./sapi/cli/php -f ext/$extname/$extname.php 7. $ vi ext/$extname/$extname.c 8. $ make diff --git a/ext/fileinfo/libmagic.patch b/ext/fileinfo/libmagic.patch index a9af5398f5..8b0b9a8911 100644 --- a/ext/fileinfo/libmagic.patch +++ b/ext/fileinfo/libmagic.patch @@ -822,7 +822,16 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c } diff -u libmagic.orig/cdf.c libmagic/cdf.c --- libmagic.orig/cdf.c Tue Feb 26 17:20:42 2013 -+++ libmagic/cdf.c Fri Feb 21 00:21:27 2014 ++++ libmagic/cdf.c Tue Jul 1 08:57:25 2014 +@@ -35,7 +35,7 @@ + #include "file.h" + + #ifndef lint +-FILE_RCSID("@(#)$File: cdf.c,v 1.53 2013/02/26 16:20:42 christos Exp $") ++FILE_RCSID("@(#)$File: cdf.c,v 1.55 2014/02/27 23:26:17 christos Exp $") + #endif + + #include <assert.h> @@ -43,7 +43,17 @@ #include <err.h> #endif @@ -841,7 +850,25 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c #include <string.h> #include <time.h> #include <ctype.h> -@@ -296,7 +306,10 @@ +@@ -267,13 +277,15 @@ + { + const char *b = (const char *)sst->sst_tab; + const char *e = ((const char *)p) + tail; ++ size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ? ++ CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h); + (void)&line; +- if (e >= b && (size_t)(e - b) <= CDF_SEC_SIZE(h) * sst->sst_len) ++ if (e >= b && (size_t)(e - b) <= ss * sst->sst_len) + return 0; + DPRINTF(("%d: offset begin %p < end %p || %" SIZE_T_FORMAT "u" + " > %" SIZE_T_FORMAT "u [%" SIZE_T_FORMAT "u %" + SIZE_T_FORMAT "u]\n", line, b, e, (size_t)(e - b), +- CDF_SEC_SIZE(h) * sst->sst_len, CDF_SEC_SIZE(h), sst->sst_len)); ++ ss * sst->sst_len, ss, sst->sst_len)); + errno = EFTYPE; + return -1; + } +@@ -296,7 +308,10 @@ if (info->i_fd == -1) return -1; @@ -853,7 +880,133 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c return -1; return (ssize_t)len; -@@ -1132,7 +1145,7 @@ +@@ -352,10 +367,10 @@ + size_t ss = CDF_SHORT_SEC_SIZE(h); + size_t pos = CDF_SHORT_SEC_POS(h, id); + assert(ss == len); +- if (pos > CDF_SEC_SIZE(h) * sst->sst_len) { ++ if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) { + DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %" + SIZE_T_FORMAT "u\n", +- pos, CDF_SEC_SIZE(h) * sst->sst_len)); ++ pos + len, CDF_SEC_SIZE(h) * sst->sst_len)); + return -1; + } + (void)memcpy(((char *)buf) + offs, +@@ -455,7 +470,8 @@ + cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) + { + size_t i, j; +- cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * size); ++ cdf_secid_t maxsector = (cdf_secid_t)((sat->sat_len * size) ++ / sizeof(maxsector)); + + DPRINTF(("Chain:")); + for (j = i = 0; sid >= 0; i++, j++) { +@@ -465,8 +481,8 @@ + errno = EFTYPE; + return (size_t)-1; + } +- if (sid > maxsector) { +- DPRINTF(("Sector %d > %d\n", sid, maxsector)); ++ if (sid >= maxsector) { ++ DPRINTF(("Sector %d >= %d\n", sid, maxsector)); + errno = EFTYPE; + return (size_t)-1; + } +@@ -675,11 +691,13 @@ + + int + cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h, +- const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn) ++ const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn, ++ const cdf_directory_t **root) + { + size_t i; + const cdf_directory_t *d; + ++ *root = NULL; + for (i = 0; i < dir->dir_len; i++) + if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_ROOT_STORAGE) + break; +@@ -688,6 +706,7 @@ + if (i == dir->dir_len) + goto out; + d = &dir->dir_tab[i]; ++ *root = d; + + /* If the it is not there, just fake it; some docs don't have it */ + if (d->d_stream_first_sector < 0) +@@ -796,7 +815,11 @@ + if (cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1) + goto out; + for (i = 0; i < sh.sh_properties; i++) { +- size_t ofs = CDF_GETUINT32(p, (i << 1) + 1); ++ size_t ofs, tail = (i << 1) + 1; ++ if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t), ++ __LINE__) == -1) ++ goto out; ++ ofs = CDF_GETUINT32(p, tail); + q = (const uint8_t *)(const void *) + ((const char *)(const void *)p + ofs + - 2 * sizeof(uint32_t)); +@@ -810,6 +833,10 @@ + i, inp[i].pi_id, inp[i].pi_type, q - p, offs)); + if (inp[i].pi_type & CDF_VECTOR) { + nelements = CDF_GETUINT32(q, 1); ++ if (nelements == 0) { ++ DPRINTF(("CDF_VECTOR with nelements == 0\n")); ++ goto out; ++ } + o = 2; + } else { + nelements = 1; +@@ -884,7 +911,9 @@ + } + DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n", + nelements)); +- for (j = 0; j < nelements; j++, i++) { ++ for (j = 0; j < nelements && i < sh.sh_properties; ++ j++, i++) ++ { + uint32_t l = CDF_GETUINT32(q, o); + inp[i].pi_str.s_len = l; + inp[i].pi_str.s_buf = (const char *) +@@ -929,7 +958,7 @@ + cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, + cdf_summary_info_header_t *ssi, cdf_property_info_t **info, size_t *count) + { +- size_t i, maxcount; ++ size_t maxcount; + const cdf_summary_info_header_t *si = + CAST(const cdf_summary_info_header_t *, sst->sst_tab); + const cdf_section_declaration_t *sd = +@@ -944,21 +973,13 @@ + ssi->si_os = CDF_TOLE2(si->si_os); + ssi->si_class = si->si_class; + cdf_swap_class(&ssi->si_class); +- ssi->si_count = CDF_TOLE2(si->si_count); ++ ssi->si_count = CDF_TOLE4(si->si_count); + *count = 0; + maxcount = 0; + *info = NULL; +- for (i = 0; i < CDF_TOLE4(si->si_count); i++) { +- if (i >= CDF_LOOP_LIMIT) { +- DPRINTF(("Unpack summary info loop limit")); +- errno = EFTYPE; +- return -1; +- } +- if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), +- info, count, &maxcount) == -1) { ++ if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), info, ++ count, &maxcount) == -1) + return -1; +- } +- } + return 0; + } + +@@ -1132,7 +1153,7 @@ cdf_directory_t *d; char name[__arraycount(d->d_name)]; cdf_stream_t scn; @@ -862,7 +1015,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c static const char *types[] = { "empty", "user storage", "user stream", "lockbytes", "property", "root storage" }; -@@ -1185,7 +1198,7 @@ +@@ -1185,7 +1206,7 @@ cdf_dump_property_info(const cdf_property_info_t *info, size_t count) { cdf_timestamp_t tp; @@ -871,7 +1024,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c char buf[64]; size_t i, j; -@@ -1229,7 +1242,11 @@ +@@ -1229,7 +1250,11 @@ break; case CDF_FILETIME: tp = info[i].pi_tp; @@ -885,7 +1038,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c } else { diff -u libmagic.orig/cdf.h libmagic/cdf.h --- libmagic.orig/cdf.h Thu Jun 21 00:19:55 2012 -+++ libmagic/cdf.h Fri Feb 21 00:21:27 2014 ++++ libmagic/cdf.h Thu Jun 5 18:05:33 2014 @@ -35,10 +35,12 @@ #ifndef _H_CDF_ #define _H_CDF_ @@ -926,6 +1079,16 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h int cdf_read_header(const cdf_info_t *, cdf_header_t *); void cdf_swap_header(cdf_header_t *); void cdf_unpack_header(cdf_header_t *, char *); +@@ -294,7 +300,8 @@ + int cdf_read_ssat(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, + cdf_sat_t *); + int cdf_read_short_stream(const cdf_info_t *, const cdf_header_t *, +- const cdf_sat_t *, const cdf_dir_t *, cdf_stream_t *); ++ const cdf_sat_t *, const cdf_dir_t *, cdf_stream_t *, ++ const cdf_directory_t **); + int cdf_read_property_info(const cdf_stream_t *, const cdf_header_t *, uint32_t, + cdf_property_info_t **, size_t *, size_t *); + int cdf_read_summary_info(const cdf_info_t *, const cdf_header_t *, diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c --- libmagic.orig/cdf_time.c Thu Jun 21 00:18:33 2012 +++ libmagic/cdf_time.c Fri Feb 21 00:21:27 2014 @@ -2543,8 +2706,13 @@ diff -u libmagic.orig/print.c libmagic/print.c } diff -u libmagic.orig/readcdf.c libmagic/readcdf.c --- libmagic.orig/readcdf.c Tue Jan 7 04:13:42 2014 -+++ libmagic/readcdf.c Fri Feb 21 00:21:27 2014 -@@ -30,7 +30,11 @@ ++++ libmagic/readcdf.c Thu Jun 5 18:05:33 2014 +@@ -26,11 +26,15 @@ + #include "file.h" + + #ifndef lint +-FILE_RCSID("@(#)$File: readcdf.c,v 1.37 2014/01/06 13:41:18 rrt Exp $") ++FILE_RCSID("@(#)$File: readcdf.c,v 1.40 2014/03/06 15:23:33 christos Exp $") #endif #include <stdlib.h> @@ -2556,7 +2724,7 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c #include <string.h> #include <time.h> #include <ctype.h> -@@ -69,6 +73,10 @@ +@@ -69,6 +73,44 @@ { NULL, NULL, }, }; @@ -2564,10 +2732,49 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c +# define strcasestr strstr +#endif + ++static const struct cv { ++ uint64_t clsid[2]; ++ const char *mime; ++} clsid2mime[] = { ++ { ++#ifdef PHP_WIN32 ++ { 0x00000000000c1084ui64, 0x46000000000000c0ui64 }, ++#else ++ { 0x00000000000c1084LLU, 0x46000000000000c0LLU }, ++#endif ++ "x-msi", ++ } ++}, clsid2desc[] = { ++ { ++#ifdef PHP_WIN32 ++ { 0x00000000000c1084ui64, 0x46000000000000c0ui64 }, ++#else ++ { 0x00000000000c1084LLU, 0x46000000000000c0LLU }, ++#endif ++ "MSI Installer", ++ }, ++}; ++ ++private const char * ++cdf_clsid_to_mime(const uint64_t clsid[2], const struct cv *cv) ++{ ++ size_t i; ++ for (i = 0; cv[i].mime != NULL; i++) { ++ if (clsid[0] == cv[i].clsid[0] && clsid[1] == cv[i].clsid[1]) ++ return cv[i].mime; ++ } ++ return NULL; ++} ++ private const char * cdf_app_to_mime(const char *vbuf, const struct nv *nv) { -@@ -91,7 +99,7 @@ +@@ -87,16 +129,21 @@ + + private int + cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, +- size_t count) ++ size_t count, const cdf_directory_t *root_storage) { size_t i; cdf_timestamp_t tp; @@ -2576,7 +2783,26 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c char buf[64]; const char *str = NULL; const char *s; -@@ -162,8 +170,12 @@ + int len; + ++ memset(&ts, 0, sizeof(ts)); ++ ++ if (!NOTMIME(ms) && root_storage) ++ str = cdf_clsid_to_mime(root_storage->d_storage_uuid, clsid2mime); ++ + for (i = 0; i < count; i++) { + cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); + switch (info[i].pi_type) { +@@ -153,7 +200,7 @@ + buf, vbuf) == -1) + return -1; + } +- } else if (info[i].pi_id == ++ } else if (str == NULL && info[i].pi_id == + CDF_PROPERTY_NAME_OF_APPLICATION) { + str = cdf_app_to_mime(vbuf, app2mime); + } +@@ -162,8 +209,12 @@ case CDF_FILETIME: tp = info[i].pi_tp; if (tp != 0) { @@ -2591,7 +2817,7 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c cdf_print_elapsed_time(tbuf, sizeof(tbuf), tp); if (NOTMIME(ms) && file_printf(ms, -@@ -171,8 +183,11 @@ +@@ -171,8 +222,11 @@ return -1; } else { char *c, *ec; @@ -2605,6 +2831,91 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c if (c != NULL && (ec = strchr(c, '\n')) != NULL) *ec = '\0'; +@@ -200,7 +254,7 @@ + + private int + cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, +- const cdf_stream_t *sst) ++ const cdf_stream_t *sst, const cdf_directory_t *root_storage) + { + cdf_summary_info_header_t si; + cdf_property_info_t *info; +@@ -211,6 +265,8 @@ + return -1; + + if (NOTMIME(ms)) { ++ const char *str; ++ + if (file_printf(ms, "Composite Document File V2 Document") + == -1) + return -1; +@@ -238,9 +294,15 @@ + return -2; + break; + } +- } ++ if (root_storage) { ++ str = cdf_clsid_to_mime(root_storage->d_storage_uuid, clsid2desc); ++ if (str) ++ if (file_printf(ms, ", %s", str) == -1) ++ return -2; ++ } ++ } + +- m = cdf_file_property_info(ms, info, count); ++ m = cdf_file_property_info(ms, info, count, root_storage); + free(info); + + return m == -1 ? -2 : m; +@@ -258,6 +320,7 @@ + int i; + const char *expn = ""; + const char *corrupt = "corrupt: "; ++ const cdf_directory_t *root_storage; + + info.i_fd = fd; + info.i_buf = buf; +@@ -291,7 +354,8 @@ + goto out2; + } + +- if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) { ++ if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst, ++ &root_storage)) == -1) { + expn = "Cannot read short stream"; + goto out3; + } +@@ -312,23 +376,21 @@ + #ifdef CDF_DEBUG + cdf_dump_summary_info(&h, &scn); + #endif +- if ((i = cdf_file_summary_info(ms, &h, &scn)) < 0) +- expn = "Can't expand summary_info"; ++ if ((i = cdf_file_summary_info(ms, &h, &scn, root_storage)) < 0) ++ expn = "Can't expand summary_info"; ++ + if (i == 0) { + const char *str = NULL; + cdf_directory_t *d; + char name[__arraycount(d->d_name)]; + size_t j, k; +- for (j = 0; j < dir.dir_len; j++) { ++ ++ for (j = 0; str == NULL && j < dir.dir_len; j++) { + d = &dir.dir_tab[j]; + for (k = 0; k < sizeof(name); k++) + name[k] = (char)cdf_tole2(d->d_name[k]); +- if (NOTMIME(ms)) +- str = cdf_app_to_mime(name, name2desc); +- else +- str = cdf_app_to_mime(name, name2mime); +- if (str != NULL) +- break; ++ str = cdf_app_to_mime(name, ++ NOTMIME(ms) ? name2desc : name2mime); + } + if (NOTMIME(ms)) { + if (str != NULL) { diff -u libmagic.orig/readelf.c libmagic/readelf.c --- libmagic.orig/readelf.c Tue Nov 5 16:44:01 2013 +++ libmagic/readelf.c Fri Feb 21 00:21:27 2014 @@ -2852,7 +3163,7 @@ diff -u libmagic.orig/readelf.h libmagic/readelf.h typedef uint8_t Elf64_Char; diff -u libmagic.orig/softmagic.c libmagic/softmagic.c --- libmagic.orig/softmagic.c Thu Feb 13 00:20:53 2014 -+++ libmagic/softmagic.c Sun Mar 9 13:14:07 2014 ++++ libmagic/softmagic.c Tue Jul 1 08:57:25 2014 @@ -50,6 +50,11 @@ #include <locale.h> #endif @@ -2987,7 +3298,29 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c break; \ } \ -@@ -1178,9 +1162,6 @@ +@@ -931,10 +915,18 @@ + return 1; + } + case FILE_PSTRING: { +- char *ptr1 = p->s, *ptr2 = ptr1 + file_pstring_length_size(m); ++ size_t sz = file_pstring_length_size(m); ++ char *ptr1 = p->s, *ptr2 = ptr1 + sz; + size_t len = file_pstring_get_length(m, ptr1); +- if (len >= sizeof(p->s)) +- len = sizeof(p->s) - 1; ++ if (len >= sizeof(p->s)) { ++ /* ++ * The size of the pascal string length (sz) ++ * is 1, 2, or 4. We need at least 1 byte for NUL ++ * termination, but we've already truncated the ++ * string by p->s, so we need to deduct sz. ++ */ ++ len = sizeof(p->s) - sz; ++ } + while (len--) + *ptr1++ = *ptr2++; + *ptr1 = '\0'; +@@ -1178,9 +1170,6 @@ "nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o, nbytes, count); mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); @@ -2997,7 +3330,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c } if (m->flag & INDIR) { -@@ -1679,9 +1660,6 @@ +@@ -1679,9 +1668,6 @@ if ((ms->flags & MAGIC_DEBUG) != 0) { mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); @@ -3007,7 +3340,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c } } -@@ -1755,11 +1733,21 @@ +@@ -1755,11 +1741,21 @@ ms->offset = soffset; if (rv == 1) { if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 && @@ -3032,7 +3365,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c } return rv; -@@ -1875,6 +1863,42 @@ +@@ -1875,6 +1871,42 @@ return file_strncmp(a, b, len, flags); } @@ -3075,13 +3408,16 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c private int magiccheck(struct magic_set *ms, struct magic *m) { -@@ -2035,63 +2059,151 @@ +@@ -2035,63 +2067,151 @@ break; } case FILE_REGEX: { - int rc; - regex_t rx; - char errmsg[512]; +- +- if (ms->search.s == NULL) +- return 0; + zval *pattern; + int options = 0; + pcre_cache_entry *pce; @@ -3218,9 +3554,6 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c + } + } -- if (ms->search.s == NULL) -- return 0; - - l = 0; - rc = regcomp(&rx, m->value.s, - REG_EXTENDED|REG_NEWLINE| @@ -3255,7 +3588,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c - (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so); - v = 0; - break; -- + - case REG_NOMATCH: + } else { v = 1; @@ -3279,3 +3612,15 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c break; } case FILE_INDIRECT: +diff -u libmagic.orig/strcasestr.c libmagic/strcasestr.c +--- libmagic.orig/strcasestr.c Thu Dec 5 17:57:50 2013 ++++ libmagic/strcasestr.c Sun May 4 21:29:20 2014 +@@ -37,6 +37,8 @@ + __RCSID("$NetBSD: strncasecmp.c,v 1.2 2007/06/04 18:19:27 christos Exp $"); + #endif /* LIBC_SCCS and not lint */ + ++#include "php_stdint.h" ++ + #include <assert.h> + #include <ctype.h> + #include <string.h> diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c index dd7177ed90..ad285cfe18 100644 --- a/ext/fileinfo/libmagic/cdf.c +++ b/ext/fileinfo/libmagic/cdf.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: cdf.c,v 1.53 2013/02/26 16:20:42 christos Exp $") +FILE_RCSID("@(#)$File: cdf.c,v 1.55 2014/02/27 23:26:17 christos Exp $") #endif #include <assert.h> @@ -277,13 +277,15 @@ cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h, { const char *b = (const char *)sst->sst_tab; const char *e = ((const char *)p) + tail; + size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ? + CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h); (void)&line; - if (e >= b && (size_t)(e - b) <= CDF_SEC_SIZE(h) * sst->sst_len) + if (e >= b && (size_t)(e - b) <= ss * sst->sst_len) return 0; DPRINTF(("%d: offset begin %p < end %p || %" SIZE_T_FORMAT "u" " > %" SIZE_T_FORMAT "u [%" SIZE_T_FORMAT "u %" SIZE_T_FORMAT "u]\n", line, b, e, (size_t)(e - b), - CDF_SEC_SIZE(h) * sst->sst_len, CDF_SEC_SIZE(h), sst->sst_len)); + ss * sst->sst_len, ss, sst->sst_len)); errno = EFTYPE; return -1; } @@ -365,10 +367,10 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, size_t ss = CDF_SHORT_SEC_SIZE(h); size_t pos = CDF_SHORT_SEC_POS(h, id); assert(ss == len); - if (pos > CDF_SEC_SIZE(h) * sst->sst_len) { + if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) { DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n", - pos, CDF_SEC_SIZE(h) * sst->sst_len)); + pos + len, CDF_SEC_SIZE(h) * sst->sst_len)); return -1; } (void)memcpy(((char *)buf) + offs, @@ -468,7 +470,8 @@ size_t cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) { size_t i, j; - cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * size); + cdf_secid_t maxsector = (cdf_secid_t)((sat->sat_len * size) + / sizeof(maxsector)); DPRINTF(("Chain:")); for (j = i = 0; sid >= 0; i++, j++) { @@ -478,8 +481,8 @@ cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) errno = EFTYPE; return (size_t)-1; } - if (sid > maxsector) { - DPRINTF(("Sector %d > %d\n", sid, maxsector)); + if (sid >= maxsector) { + DPRINTF(("Sector %d >= %d\n", sid, maxsector)); errno = EFTYPE; return (size_t)-1; } @@ -688,11 +691,13 @@ out: int cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h, - const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn) + const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn, + const cdf_directory_t **root) { size_t i; const cdf_directory_t *d; + *root = NULL; for (i = 0; i < dir->dir_len; i++) if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_ROOT_STORAGE) break; @@ -701,6 +706,7 @@ cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h, if (i == dir->dir_len) goto out; d = &dir->dir_tab[i]; + *root = d; /* If the it is not there, just fake it; some docs don't have it */ if (d->d_stream_first_sector < 0) @@ -809,7 +815,11 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, if (cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1) goto out; for (i = 0; i < sh.sh_properties; i++) { - size_t ofs = CDF_GETUINT32(p, (i << 1) + 1); + size_t ofs, tail = (i << 1) + 1; + if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t), + __LINE__) == -1) + goto out; + ofs = CDF_GETUINT32(p, tail); q = (const uint8_t *)(const void *) ((const char *)(const void *)p + ofs - 2 * sizeof(uint32_t)); @@ -823,6 +833,10 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, i, inp[i].pi_id, inp[i].pi_type, q - p, offs)); if (inp[i].pi_type & CDF_VECTOR) { nelements = CDF_GETUINT32(q, 1); + if (nelements == 0) { + DPRINTF(("CDF_VECTOR with nelements == 0\n")); + goto out; + } o = 2; } else { nelements = 1; @@ -897,7 +911,9 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, } DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n", nelements)); - for (j = 0; j < nelements; j++, i++) { + for (j = 0; j < nelements && i < sh.sh_properties; + j++, i++) + { uint32_t l = CDF_GETUINT32(q, o); inp[i].pi_str.s_len = l; inp[i].pi_str.s_buf = (const char *) @@ -942,7 +958,7 @@ int cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, cdf_summary_info_header_t *ssi, cdf_property_info_t **info, size_t *count) { - size_t i, maxcount; + size_t maxcount; const cdf_summary_info_header_t *si = CAST(const cdf_summary_info_header_t *, sst->sst_tab); const cdf_section_declaration_t *sd = @@ -957,21 +973,13 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, ssi->si_os = CDF_TOLE2(si->si_os); ssi->si_class = si->si_class; cdf_swap_class(&ssi->si_class); - ssi->si_count = CDF_TOLE2(si->si_count); + ssi->si_count = CDF_TOLE4(si->si_count); *count = 0; maxcount = 0; *info = NULL; - for (i = 0; i < CDF_TOLE4(si->si_count); i++) { - if (i >= CDF_LOOP_LIMIT) { - DPRINTF(("Unpack summary info loop limit")); - errno = EFTYPE; - return -1; - } - if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), - info, count, &maxcount) == -1) { + if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), info, + count, &maxcount) == -1) return -1; - } - } return 0; } diff --git a/ext/fileinfo/libmagic/cdf.h b/ext/fileinfo/libmagic/cdf.h index 70eb519465..00131e02f4 100644 --- a/ext/fileinfo/libmagic/cdf.h +++ b/ext/fileinfo/libmagic/cdf.h @@ -300,7 +300,8 @@ int cdf_read_dir(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, int cdf_read_ssat(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, cdf_sat_t *); int cdf_read_short_stream(const cdf_info_t *, const cdf_header_t *, - const cdf_sat_t *, const cdf_dir_t *, cdf_stream_t *); + const cdf_sat_t *, const cdf_dir_t *, cdf_stream_t *, + const cdf_directory_t **); int cdf_read_property_info(const cdf_stream_t *, const cdf_header_t *, uint32_t, cdf_property_info_t **, size_t *, size_t *); int cdf_read_summary_info(const cdf_info_t *, const cdf_header_t *, diff --git a/ext/fileinfo/libmagic/readcdf.c b/ext/fileinfo/libmagic/readcdf.c index 66a18dbb87..ec97ced44b 100644 --- a/ext/fileinfo/libmagic/readcdf.c +++ b/ext/fileinfo/libmagic/readcdf.c @@ -26,7 +26,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readcdf.c,v 1.37 2014/01/06 13:41:18 rrt Exp $") +FILE_RCSID("@(#)$File: readcdf.c,v 1.40 2014/03/06 15:23:33 christos Exp $") #endif #include <stdlib.h> @@ -77,6 +77,40 @@ static const struct nv { # define strcasestr strstr #endif +static const struct cv { + uint64_t clsid[2]; + const char *mime; +} clsid2mime[] = { + { +#ifdef PHP_WIN32 + { 0x00000000000c1084ui64, 0x46000000000000c0ui64 }, +#else + { 0x00000000000c1084LLU, 0x46000000000000c0LLU }, +#endif + "x-msi", + } +}, clsid2desc[] = { + { +#ifdef PHP_WIN32 + { 0x00000000000c1084ui64, 0x46000000000000c0ui64 }, +#else + { 0x00000000000c1084LLU, 0x46000000000000c0LLU }, +#endif + "MSI Installer", + }, +}; + +private const char * +cdf_clsid_to_mime(const uint64_t clsid[2], const struct cv *cv) +{ + size_t i; + for (i = 0; cv[i].mime != NULL; i++) { + if (clsid[0] == cv[i].clsid[0] && clsid[1] == cv[i].clsid[1]) + return cv[i].mime; + } + return NULL; +} + private const char * cdf_app_to_mime(const char *vbuf, const struct nv *nv) { @@ -95,7 +129,7 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv) private int cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, - size_t count) + size_t count, const cdf_directory_t *root_storage) { size_t i; cdf_timestamp_t tp; @@ -105,6 +139,11 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, const char *s; int len; + memset(&ts, 0, sizeof(ts)); + + if (!NOTMIME(ms) && root_storage) + str = cdf_clsid_to_mime(root_storage->d_storage_uuid, clsid2mime); + for (i = 0; i < count; i++) { cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); switch (info[i].pi_type) { @@ -161,7 +200,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, buf, vbuf) == -1) return -1; } - } else if (info[i].pi_id == + } else if (str == NULL && info[i].pi_id == CDF_PROPERTY_NAME_OF_APPLICATION) { str = cdf_app_to_mime(vbuf, app2mime); } @@ -215,7 +254,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, private int cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, - const cdf_stream_t *sst) + const cdf_stream_t *sst, const cdf_directory_t *root_storage) { cdf_summary_info_header_t si; cdf_property_info_t *info; @@ -226,6 +265,8 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, return -1; if (NOTMIME(ms)) { + const char *str; + if (file_printf(ms, "Composite Document File V2 Document") == -1) return -1; @@ -253,9 +294,15 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, return -2; break; } - } + if (root_storage) { + str = cdf_clsid_to_mime(root_storage->d_storage_uuid, clsid2desc); + if (str) + if (file_printf(ms, ", %s", str) == -1) + return -2; + } + } - m = cdf_file_property_info(ms, info, count); + m = cdf_file_property_info(ms, info, count, root_storage); free(info); return m == -1 ? -2 : m; @@ -273,6 +320,7 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, int i; const char *expn = ""; const char *corrupt = "corrupt: "; + const cdf_directory_t *root_storage; info.i_fd = fd; info.i_buf = buf; @@ -306,7 +354,8 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, goto out2; } - if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) { + if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst, + &root_storage)) == -1) { expn = "Cannot read short stream"; goto out3; } @@ -327,23 +376,21 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, #ifdef CDF_DEBUG cdf_dump_summary_info(&h, &scn); #endif - if ((i = cdf_file_summary_info(ms, &h, &scn)) < 0) - expn = "Can't expand summary_info"; + if ((i = cdf_file_summary_info(ms, &h, &scn, root_storage)) < 0) + expn = "Can't expand summary_info"; + if (i == 0) { const char *str = NULL; cdf_directory_t *d; char name[__arraycount(d->d_name)]; size_t j, k; - for (j = 0; j < dir.dir_len; j++) { + + for (j = 0; str == NULL && j < dir.dir_len; j++) { d = &dir.dir_tab[j]; for (k = 0; k < sizeof(name); k++) name[k] = (char)cdf_tole2(d->d_name[k]); - if (NOTMIME(ms)) - str = cdf_app_to_mime(name, name2desc); - else - str = cdf_app_to_mime(name, name2mime); - if (str != NULL) - break; + str = cdf_app_to_mime(name, + NOTMIME(ms) ? name2desc : name2mime); } if (NOTMIME(ms)) { if (str != NULL) { diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c index 1d5db8966a..3dd07820a4 100644 --- a/ext/fileinfo/libmagic/softmagic.c +++ b/ext/fileinfo/libmagic/softmagic.c @@ -915,10 +915,18 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) return 1; } case FILE_PSTRING: { - char *ptr1 = p->s, *ptr2 = ptr1 + file_pstring_length_size(m); + size_t sz = file_pstring_length_size(m); + char *ptr1 = p->s, *ptr2 = ptr1 + sz; size_t len = file_pstring_get_length(m, ptr1); - if (len >= sizeof(p->s)) - len = sizeof(p->s) - 1; + if (len >= sizeof(p->s)) { + /* + * The size of the pascal string length (sz) + * is 1, 2, or 4. We need at least 1 byte for NUL + * termination, but we've already truncated the + * string by p->s, so we need to deduct sz. + */ + len = sizeof(p->s) - sz; + } while (len--) *ptr1++ = *ptr2++; *ptr1 = '\0'; diff --git a/ext/fileinfo/libmagic/strcasestr.c b/ext/fileinfo/libmagic/strcasestr.c index 546ed3f96c..e1434e69e7 100644 --- a/ext/fileinfo/libmagic/strcasestr.c +++ b/ext/fileinfo/libmagic/strcasestr.c @@ -37,6 +37,8 @@ __RCSID("$NetBSD: strcasestr.c,v 1.3 2005/11/29 03:12:00 christos Exp $"); __RCSID("$NetBSD: strncasecmp.c,v 1.2 2007/06/04 18:19:27 christos Exp $"); #endif /* LIBC_SCCS and not lint */ +#include "php_stdint.h" + #include <assert.h> #include <ctype.h> #include <string.h> diff --git a/ext/fileinfo/tests/finfo_file_002.phpt b/ext/fileinfo/tests/finfo_file_002.phpt index feb4010f74..5cce7f3f9b 100644 --- a/ext/fileinfo/tests/finfo_file_002.phpt +++ b/ext/fileinfo/tests/finfo_file_002.phpt @@ -18,7 +18,7 @@ ksort($results); var_dump($results); ?> --EXPECTF-- -array(8) { +array(9) { ["%s/resources/dir.zip"]=> string(15) "application/zip" ["%s/resources/test.awk"]=> @@ -35,4 +35,6 @@ array(8) { string(15) "application/pdf" ["%s/resources/test.png"]=> string(9) "image/png" + ["%s/resources/test.ppt"]=> + string(29) "application/vnd.ms-powerpoint" } diff --git a/ext/fileinfo/tests/resources/test.ppt b/ext/fileinfo/tests/resources/test.ppt Binary files differnew file mode 100644 index 0000000000..713004c03d --- /dev/null +++ b/ext/fileinfo/tests/resources/test.ppt diff --git a/ext/filter/tests/bug49184.phpt b/ext/filter/tests/bug49184.phpt new file mode 100644 index 0000000000..86d35db0d5 --- /dev/null +++ b/ext/filter/tests/bug49184.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #67296 (filter_input doesn't validate variables) +--XFAIL-- +See Bug #49184 +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip needs filter ext"); ?> +--ENV-- +return <<<END +HTTP_X_FORWARDED_FOR=example.com +END; +--FILE-- +<?php + var_dump(filter_input(INPUT_SERVER, "HTTP_X_FORWARDED_FOR", FILTER_UNSAFE_RAW)); + var_dump($_SERVER["HTTP_X_FORWARDED_FOR"]); + var_dump(getenv("HTTP_X_FORWARDED_FOR")); + var_dump("done"); +?> +--EXPECT-- +string(11) "example.com" +string(11) "example.com" +string(11) "example.com" +string(4) "done" diff --git a/ext/gd/gd.c b/ext/gd/gd.c index f54fb9ff8a..f67e80bf8e 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -5274,7 +5274,7 @@ PHP_FUNCTION(imageaffinematrixget) { double affine[6]; long type; - zval *options; + zval *options = NULL; zval **tmp; int res = GD_FALSE, i; @@ -5286,7 +5286,7 @@ PHP_FUNCTION(imageaffinematrixget) case GD_AFFINE_TRANSLATE: case GD_AFFINE_SCALE: { double x, y; - if (Z_TYPE_P(options) != IS_ARRAY) { + if (!options || Z_TYPE_P(options) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array expected as options"); RETURN_FALSE; } @@ -5333,6 +5333,10 @@ PHP_FUNCTION(imageaffinematrixget) case GD_AFFINE_SHEAR_VERTICAL: { double angle; + if (!options) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number is expected as option"); + RETURN_FALSE; + } convert_to_double_ex(&options); angle = Z_DVAL_P(options); diff --git a/ext/gd/tests/bug67248.phpt b/ext/gd/tests/bug67248.phpt new file mode 100644 index 0000000000..9c83966a60 --- /dev/null +++ b/ext/gd/tests/bug67248.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #67248 (imageaffinematrixget missing check of parameters) +--SKIPIF-- +<?php + if(!extension_loaded('gd')){ die('skip gd extension not available')} + if(!function_exists('imageaffinematrixget')) die('skip imageaffinematrixget() not available'); +?> +--FILE-- +<?php +for($i=0;$i<7;$i++) { + imageaffinematrixget($i); +} +?> +--EXPECTF-- +Warning: imageaffinematrixget(): Array expected as options in %s on line %d + +Warning: imageaffinematrixget(): Array expected as options in %s on line %d + +Warning: imageaffinematrixget(): Number is expected as option in %s on line %d + +Warning: imageaffinematrixget(): Number is expected as option in %s on line %d + +Warning: imageaffinematrixget(): Number is expected as option in %s on line %d + +Warning: imageaffinematrixget(): Invalid type for element 5 in %s on line %d + +Warning: imageaffinematrixget(): Invalid type for element 6 in %s on line %d diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index d34d78f01a..cd50896cc7 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -575,22 +575,20 @@ static int gmp_serialize(zval *object, unsigned char **buffer, zend_uint *buf_le 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; - - PHP_VAR_SERIALIZE_INIT(*serialize_data); + php_serialize_data_t serialize_data = (php_serialize_data_t) data; + 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); + 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); + 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; @@ -604,17 +602,16 @@ static int gmp_unserialize(zval **object, zend_class_entry *ce, const unsigned c 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); + 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) + 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 ) { @@ -624,7 +621,7 @@ static int gmp_unserialize(zval **object, zend_class_entry *ce, const unsigned c zval_dtor(&zv); INIT_ZVAL(zv); - if (!php_var_unserialize(&zv_ptr, &p, max, unserialize_data TSRMLS_CC) + if (!php_var_unserialize(&zv_ptr, &p, max, &unserialize_data TSRMLS_CC) || Z_TYPE_P(zv_ptr) != IS_ARRAY ) { zend_throw_exception(NULL, "Could not unserialize properties", 0 TSRMLS_CC); @@ -641,7 +638,7 @@ static int gmp_unserialize(zval **object, zend_class_entry *ce, const unsigned c retval = SUCCESS; exit: zval_dtor(&zv); - PHP_VAR_UNSERIALIZE_DESTROY(*unserialize_data); + PHP_VAR_UNSERIALIZE_DESTROY(unserialize_data); return retval; } /* }}} */ diff --git a/ext/interbase/php_ibase_includes.h b/ext/interbase/php_ibase_includes.h index c994a92da5..6671c9162d 100644 --- a/ext/interbase/php_ibase_includes.h +++ b/ext/interbase/php_ibase_includes.h @@ -35,6 +35,7 @@ #define IB_STATUS (IBG(status)) +/* XXX ZEND_DEBUG_ is misleading, it should be something like IBASE_DEBUG. */ #ifdef ZEND_DEBUG_ #define IBDEBUG(a) php_printf("::: %s (%d)\n", a, __LINE__); #endif diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index 21b5847f2d..f1e184914d 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -269,8 +269,7 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int* grOffset = findOffset( LOC_GRANDFATHERED , loc_name ); if( grOffset >= 0 ){ if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ - tag_value = estrdup(loc_name); - return tag_value; + return estrdup(loc_name); } else { /* Since Grandfathered , no value , do nothing , retutn NULL */ return NULL; @@ -280,8 +279,8 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int* if( fromParseLocale==1 ){ /* Handle singletons */ if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ - if( strlen(loc_name)>1 && (isIDPrefix(loc_name) ==1 ) ){ - return (char *)loc_name; + if( strlen(loc_name)>1 && (isIDPrefix(loc_name) == 1) ){ + return estrdup(loc_name); } } @@ -498,6 +497,14 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME RETURN_FALSE; } + if(loc_name_len > ULOC_FULLNAME_CAPACITY) { + /* See bug 67397: overlong locale names cause trouble in uloc_getDisplayName */ + spprintf(&msg , 0, "locale_get_display_%s : name too long", tag_name ); + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, msg , 1 TSRMLS_CC ); + efree(msg); + RETURN_FALSE; + } + if(loc_name_len == 0) { loc_name = intl_locale_get_default(TSRMLS_C); } diff --git a/ext/intl/tests/bug62082.phpt b/ext/intl/tests/bug62082.phpt index e6ca73e300..dab1252afd 100644 --- a/ext/intl/tests/bug62082.phpt +++ b/ext/intl/tests/bug62082.phpt @@ -10,6 +10,7 @@ var_dump(locale_get_display_name(str_repeat("a", 300), null)); var_dump(locale_get_display_name(str_repeat("a", 512), null)); var_dump(locale_get_display_name(str_repeat("a", 600), null)); --EXPECT-- -string(300) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" -string(512) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" -string(600) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +bool(false) +bool(false) +bool(false) + diff --git a/ext/intl/tests/bug67397.phpt b/ext/intl/tests/bug67397.phpt new file mode 100644 index 0000000000..b2b2911f8a --- /dev/null +++ b/ext/intl/tests/bug67397.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #67397 (Buffer overflow in locale_get_display_name->uloc_getDisplayName (libicu 4.8.1)) +--SKIPIF-- +<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?> +--FILE-- +<?php + +function ut_main() +{ + $ret = var_export(ut_loc_get_display_name(str_repeat('*', 256), 'en_us'), true); + $ret .= "\n"; + $ret .= var_export(intl_get_error_message(), true); + return $ret; +} + +include_once( 'ut_common.inc' ); +ut_run(); +?> +--EXPECTF-- +false +'locale_get_display_name : name too long: U_ILLEGAL_ARGUMENT_ERROR' diff --git a/ext/intl/tests/dateformat_format.phpt b/ext/intl/tests/dateformat_format.phpt index 8b410876c0..f9a90684dd 100644 --- a/ext/intl/tests/dateformat_format.phpt +++ b/ext/intl/tests/dateformat_format.phpt @@ -318,7 +318,7 @@ 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', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -326,7 +326,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : Thursday, December 31, 2009 3:02:03 PM GMT-10:00 ------------ Date is: DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -334,7 +334,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : December 31, 2009 3:02:03 PM GMT-10:00 ------------ Date is: DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -342,7 +342,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : Dec 31, 2009 3:02:03 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -350,7 +350,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : 12/31/09 3:02 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -358,7 +358,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : 20091231 03:02 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 2, 'timezone' => 'PDT', )) @@ -366,7 +366,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : Saturday, December 30, 2000 5:04:05 PM GMT-10:00 ------------ Date is: DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 2, 'timezone' => 'PDT', )) @@ -374,7 +374,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : December 30, 2000 5:04:05 PM GMT-10:00 ------------ Date is: DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 2, 'timezone' => 'PDT', )) @@ -382,7 +382,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : Dec 30, 2000 5:04:05 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 2, 'timezone' => 'PDT', )) @@ -390,7 +390,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : 12/30/00 5:04 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 2, 'timezone' => 'PDT', )) diff --git a/ext/intl/tests/dateformat_format_variant2.phpt b/ext/intl/tests/dateformat_format_variant2.phpt index eb606a53db..07c67e9322 100644 --- a/ext/intl/tests/dateformat_format_variant2.phpt +++ b/ext/intl/tests/dateformat_format_variant2.phpt @@ -318,7 +318,7 @@ 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', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -326,7 +326,7 @@ Date is: DateTime::__set_state(array( 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', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -334,7 +334,7 @@ Date is: DateTime::__set_state(array( 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', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -342,7 +342,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : Dec 31, 2009, 3:02:03 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -350,7 +350,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : 12/31/09, 3:02 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -358,7 +358,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : 20091231 03:02 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 3, 'timezone' => 'America/Los_Angeles', )) @@ -366,7 +366,7 @@ Date is: DateTime::__set_state(array( 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', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 3, 'timezone' => 'America/Los_Angeles', )) @@ -374,7 +374,7 @@ Date is: DateTime::__set_state(array( 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', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 3, 'timezone' => 'America/Los_Angeles', )) @@ -382,7 +382,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : Dec 30, 2000, 5:04:05 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 3, 'timezone' => 'America/Los_Angeles', )) @@ -390,7 +390,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : 12/30/00, 5:04 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 3, 'timezone' => 'America/Los_Angeles', )) diff --git a/ext/intl/tests/dateformat_format_variant3.phpt b/ext/intl/tests/dateformat_format_variant3.phpt index 40d49c8dc3..d770473f44 100644 --- a/ext/intl/tests/dateformat_format_variant3.phpt +++ b/ext/intl/tests/dateformat_format_variant3.phpt @@ -318,7 +318,7 @@ 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', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -326,7 +326,7 @@ Date is: DateTime::__set_state(array( 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', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -334,7 +334,7 @@ Date is: DateTime::__set_state(array( 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', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -342,7 +342,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : Dec 31, 2009, 3:02:03 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -350,7 +350,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : 12/31/09, 3:02 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03', + 'date' => '2010-01-01 01:02:03.000000', 'timezone_type' => 3, 'timezone' => 'UTC', )) @@ -358,7 +358,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : 20091231 03:02 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 2, 'timezone' => 'PDT', )) @@ -366,7 +366,7 @@ Date is: DateTime::__set_state(array( 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', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 2, 'timezone' => 'PDT', )) @@ -374,7 +374,7 @@ Date is: DateTime::__set_state(array( 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', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 2, 'timezone' => 'PDT', )) @@ -382,7 +382,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : Dec 30, 2000, 5:04:05 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 2, 'timezone' => 'PDT', )) @@ -390,7 +390,7 @@ Date is: DateTime::__set_state(array( Formatted DateTime is : 12/30/00, 5:04 PM ------------ Date is: DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05', + 'date' => '2000-12-30 19:04:05.000000', 'timezone_type' => 2, 'timezone' => 'PDT', )) diff --git a/ext/intl/tests/dateformat_localtime.phpt b/ext/intl/tests/dateformat_localtime.phpt index 79f297db74..4d185c232d 100644 --- a/ext/intl/tests/dateformat_localtime.phpt +++ b/ext/intl/tests/dateformat_localtime.phpt @@ -3,6 +3,8 @@ datefmt_localtime_code() icu <= 4.2 --SKIPIF-- <?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?> <?php if(version_compare(INTL_ICU_VERSION, '4.3', '<') != 1) print 'skip'; ?> +--INI-- +date.timezone=UTC --FILE-- <?php diff --git a/ext/intl/tests/locale_parse_locale2.phpt b/ext/intl/tests/locale_parse_locale2.phpt index 6012862a48..30cc8cc0ae 100644 --- a/ext/intl/tests/locale_parse_locale2.phpt +++ b/ext/intl/tests/locale_parse_locale2.phpt @@ -63,7 +63,8 @@ function ut_main() //Some Invalid Tags: 'de-419-DE', 'a-DE', - 'ar-a-aaa-b-bbb-a-ccc' + 'ar-a-aaa-b-bbb-a-ccc', + 'x-AAAAAA', ); @@ -201,3 +202,6 @@ No values found from Locale parsing. --------------------- ar-a-aaa-b-bbb-a-ccc: language : 'ar' , +--------------------- +x-AAAAAA: +private0 : 'AAAAAA' , diff --git a/ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt b/ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt index c9c45940b9..9581927043 100644 --- a/ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt +++ b/ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt @@ -37,6 +37,7 @@ libxml_set_external_entity_loader( ); $dd = new DOMDocument; +$dd->substituteEntities = true; $dd->resolveExternals = true; $r = $dd->loadXML($xml); var_dump($dd->validate()); diff --git a/ext/mbstring/libmbfl/cvsclean b/ext/mbstring/libmbfl/cvsclean deleted file mode 100755 index 60ae246a50..0000000000 --- a/ext/mbstring/libmbfl/cvsclean +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -function cvsclean_sub() { - prev_pwd=`pwd` - cd $1 - cat .cvsignore | while read fname; do - rm -r -f $fname - done - cd "$prev_pwd" -} - -cvsclean_sub . -cvsclean_sub mbfl -cvsclean_sub filters -cvsclean_sub nls diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index 4b1b924d06..9ea2970393 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -64,8 +64,8 @@ static void php_mb_regex_free_cache(php_mb_regex_t **pre) /* {{{ _php_mb_regex_globals_ctor */ static int _php_mb_regex_globals_ctor(zend_mb_regex_globals *pglobals TSRMLS_DC) { - pglobals->default_mbctype = ONIG_ENCODING_EUC_JP; - pglobals->current_mbctype = ONIG_ENCODING_EUC_JP; + pglobals->default_mbctype = ONIG_ENCODING_UTF8; + pglobals->current_mbctype = ONIG_ENCODING_UTF8; zend_hash_init(&(pglobals->ht_rc), 0, NULL, (void (*)(void *)) php_mb_regex_free_cache, 1); pglobals->search_str = (zval*) NULL; pglobals->search_re = (php_mb_regex_t*)NULL; diff --git a/ext/mbstring/tests/mb_eregi_replace.phpt b/ext/mbstring/tests/mb_eregi_replace.phpt index 22ba0af13d..0405d8984c 100644 --- a/ext/mbstring/tests/mb_eregi_replace.phpt +++ b/ext/mbstring/tests/mb_eregi_replace.phpt @@ -27,8 +27,9 @@ function do_translit($st) { $st = mb_eregi_replace($i,$u,$st); } return $st; -} +} +mb_regex_encoding('ISO-8859-1'); echo do_translit("Пеар"); ?> --EXPECT-- diff --git a/ext/mbstring/tests/zend_multibyte-08.phpt b/ext/mbstring/tests/zend_multibyte-08.phpt index 9e5b75eadd..561ad64038 100644 --- a/ext/mbstring/tests/zend_multibyte-08.phpt +++ b/ext/mbstring/tests/zend_multibyte-08.phpt @@ -1,5 +1,8 @@ --TEST-- zend multibyte (8) +--SKIPIF-- +--XFAIL-- +https://bugs.php.net/bug.php?id=66582 - still leaks memory which causes fail in debug mode --INI-- zend.multibyte=On zend.script_encoding=ISO-8859-1 diff --git a/ext/mbstring/tests/zend_multibyte-10.phpt b/ext/mbstring/tests/zend_multibyte-10.phpt index 138b4899fe..b4f85e6f35 100644 --- a/ext/mbstring/tests/zend_multibyte-10.phpt +++ b/ext/mbstring/tests/zend_multibyte-10.phpt @@ -1,5 +1,8 @@ --TEST-- zend multibyte (10) +--SKIPIF-- +--XFAIL-- +https://bugs.php.net/bug.php?id=66582 - still leaks memory which causes fail in debug mode --INI-- zend.multibyte=1 --FILE-- diff --git a/ext/mbstring/tests/zend_multibyte-11.phpt b/ext/mbstring/tests/zend_multibyte-11.phpt index 6844d06370..eadbb2156d 100644 --- a/ext/mbstring/tests/zend_multibyte-11.phpt +++ b/ext/mbstring/tests/zend_multibyte-11.phpt @@ -1,5 +1,8 @@ --TEST-- zend multibyte (11) +--SKIPIF-- +--XFAIL-- +https://bugs.php.net/bug.php?id=66582 - still leaks memory which causes fail in debug mode --INI-- zend.multibyte=1 --FILE-- diff --git a/ext/mysql/tests/mysql_trace_mode.phpt b/ext/mysql/tests/mysql_trace_mode.phpt index 7655975d70..73872de1db 100644 --- a/ext/mysql/tests/mysql_trace_mode.phpt +++ b/ext/mysql/tests/mysql_trace_mode.phpt @@ -31,7 +31,7 @@ require_once("clean_table.inc"); --EXPECTF-- Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d I don\'t mind character sets, do I?\n -Warning: mysql_query(): 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 'BOGUS_SQL' at line 1 in %s on line %d +Warning: mysql_query(): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'BOGUS_SQL' at line 1 in %s on line %d done! Warning: Unknown: 1 result set(s) not freed. Use mysql_free_result to free result sets which were requested using mysql_query() in %s on line %d diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 00cbcf204c..de5cd567bb 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -575,7 +575,11 @@ PHP_FUNCTION(mysqli_query) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty query"); RETURN_FALSE; } +#ifdef MYSQLI_USE_MYSQLND if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) != MYSQLI_STORE_RESULT) { +#else + if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~MYSQLI_ASYNC) != MYSQLI_STORE_RESULT) { +#endif php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode"); RETURN_FALSE; } @@ -609,7 +613,11 @@ PHP_FUNCTION(mysqli_query) RETURN_TRUE; } +#ifdef MYSQLI_USE_MYSQLND switch (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) { +#else + switch (resultmode & ~MYSQLI_ASYNC) { +#endif case MYSQLI_STORE_RESULT: #ifdef MYSQLI_USE_MYSQLND if (resultmode & MYSQLI_STORE_RESULT_COPY_DATA) { diff --git a/ext/mysqli/mysqli_priv.h b/ext/mysqli/mysqli_priv.h index e28caebf92..b1bfb56a8d 100644 --- a/ext/mysqli/mysqli_priv.h +++ b/ext/mysqli/mysqli_priv.h @@ -118,7 +118,7 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRML #else /* libmysql */ #define MYSQLI_ASYNC 0 -#define MYSQLI_STORE_RESULT_OFS 0 +#define MYSQLI_STORE_RESULT_COPY_DATA 0 #endif /* for mysqli_fetch_assoc */ diff --git a/ext/mysqli/tests/mysqli_driver.phpt b/ext/mysqli/tests/mysqli_driver.phpt index 023e4d2299..02223809ee 100644 --- a/ext/mysqli/tests/mysqli_driver.phpt +++ b/ext/mysqli/tests/mysqli_driver.phpt @@ -110,5 +110,5 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> --EXPECTF-- -Warning: mysqli_query(): (%d/%d): 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 'NO_SQL' at line 1 in %s on line %d +Warning: mysqli_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'NO_SQL' at line 1 in %s on line %d done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_report.phpt b/ext/mysqli/tests/mysqli_report.phpt index 4d2d3553d1..3dcf4981b8 100644 --- a/ext/mysqli/tests/mysqli_report.phpt +++ b/ext/mysqli/tests/mysqli_report.phpt @@ -284,19 +284,19 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_multi_query(): (%d/%d): 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 'BAR; FOO' at line 1 in %s on line %d +Warning: mysqli_multi_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'BAR; FOO' at line 1 in %s on line %d -Warning: mysqli_query(): (%d/%d): 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 'FOO' at line 1 in %s on line %d +Warning: mysqli_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d Warning: mysqli_kill(): processid should have positive value in %s on line %d -Warning: mysqli_prepare(): (%d/%d): 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 'FOO' at line 1 in %s on line %d +Warning: mysqli_prepare(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d -Warning: mysqli_real_query(): (%d/%d): 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 'FOO' at line 1 in %s on line %d +Warning: mysqli_real_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d Warning: mysqli_kill(): processid should have positive value in %s on line %d -Warning: mysqli_stmt_prepare(): (%d/%d): 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 'FOO' at line 1 in %s on line %d +Warning: mysqli_stmt_prepare(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d [013] Access denied for user '%s'@'%s' (using password: YES) [016] Access denied for user '%s'@'%s' (using password: YES) done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_report_wo_ps.phpt b/ext/mysqli/tests/mysqli_report_wo_ps.phpt index dae81b21cc..2665793407 100644 --- a/ext/mysqli/tests/mysqli_report_wo_ps.phpt +++ b/ext/mysqli/tests/mysqli_report_wo_ps.phpt @@ -104,15 +104,15 @@ if (mysqli_get_server_version($link) >= 50600) require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_multi_query(): (%d/%d): 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 'BAR; FOO' at line 1 in %s on line %d +Warning: mysqli_multi_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'BAR; FOO' at line 1 in %s on line %d -Warning: mysqli_query(): (%d/%d): 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 'FOO' at line 1 in %s on line %d +Warning: mysqli_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d Warning: mysqli_change_user(): (%d/%d): Access denied for user '%s'@'%s' (using password: %s) in %s on line %d Warning: mysqli_kill(): processid should have positive value in %s on line %d -Warning: mysqli_real_query(): (%d/%d): 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 'FOO' at line 1 in %s on line %d +Warning: mysqli_real_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d Warning: mysqli_kill(): processid should have positive value in %s on line %d [011] Access denied for user '%s'@'%s' (using password: YES) diff --git a/ext/mysqli/tests/table.inc b/ext/mysqli/tests/table.inc index aa1207af44..cb089bb950 100644 --- a/ext/mysqli/tests/table.inc +++ b/ext/mysqli/tests/table.inc @@ -12,7 +12,7 @@ if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { exit(1); } -if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . $engine)) { +if (!mysqli_query($link, 'CREATE TABLE test(id INT DEFAULT 0, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . $engine)) { printf("Failed to create test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); exit(1); } diff --git a/ext/mysqlnd/mysqlnd_charset.c b/ext/mysqlnd/mysqlnd_charset.c index c2f2b8890e..dfa90db255 100644 --- a/ext/mysqlnd/mysqlnd_charset.c +++ b/ext/mysqlnd/mysqlnd_charset.c @@ -418,20 +418,60 @@ static uint mysqlnd_mbcharlen_utf16(unsigned int utf16) /* {{{ utf32 functions */ -static uint -check_mb_utf32(const char *start __attribute((unused)), const char *end __attribute((unused))) +static unsigned int check_mb_utf32(const char *start __attribute((unused)), const char *end __attribute((unused))) { return 4; } -static uint -mysqlnd_mbcharlen_utf32(unsigned int utf32 __attribute((unused))) +static unsigned int mysqlnd_mbcharlen_utf32(unsigned int utf32 __attribute((unused))) { return 4; } /* }}} */ + +/* {{{ gb18030 functions */ +#define is_gb18030_odd(c) (0x81 <= (zend_uchar) (c) && (zend_uchar) (c) <= 0xFE) +#define is_gb18030_even_2(c) ((0x40 <= (zend_uchar) (c) && (zend_uchar) (c) <= 0x7E) || (0x80 <= (zend_uchar) (c) && (zend_uchar) (c) <= 0xFE)) +#define is_gb18030_even_4(c) (0x30 <= (zend_uchar) (c) && (zend_uchar) (c) <= 0x39) + + +static unsigned int mysqlnd_mbcharlen_gb18030(unsigned int c) +{ + if (c <= 0xFF) { + return !is_gb18030_odd(c); + } + if (c > 0xFFFF || !is_gb18030_odd((c >> 8) & 0xFF)) { + return 0; + } + if (is_gb18030_even_2((c & 0xFF))) { + return 2; + } + if (is_gb18030_even_4((c & 0xFF))) { + return 4; + } + + return 0; +} + + +static unsigned int my_ismbchar_gb18030(const char * start, const char * end) +{ + if (end - start <= 1 || !is_gb18030_odd(start[0])) { + return 0; + } + + if (is_gb18030_even_2(start[1])) { + return 2; + } else if (end - start > 3 && is_gb18030_even_4(start[1]) && is_gb18030_odd(start[2]) && is_gb18030_even_4(start[3])) { + return 4; + } + + return 0; +} +/* }}} */ + /* The server compiles sometimes the full utf-8 (the mb4) as utf8m4, and the old as utf8, for BC reasons. Sometimes, utf8mb4 is just utf8 but the old charsets are utf8mb3. @@ -643,6 +683,8 @@ const MYSQLND_CHARSET mysqlnd_charsets[] = { 245, UTF8_MB4, UTF8_MB4"_croatian_ci", 1, 4, "", mysqlnd_mbcharlen_utf8, check_mb_utf8_valid}, { 246, UTF8_MB4, UTF8_MB4"_unicode_520_ci", 1, 4, "", mysqlnd_mbcharlen_utf8, check_mb_utf8_valid}, { 247, UTF8_MB4, UTF8_MB4"_vietnamese_ci", 1, 4, "", mysqlnd_mbcharlen_utf8, check_mb_utf8_valid}, + { 248, "gb18030", "gb18030_chinese_ci", 1, 4, "", mysqlnd_mbcharlen_gb18030, my_ismbchar_gb18030}, + { 249, "gb18030", "gb18030_bin", 1, 4, "", mysqlnd_mbcharlen_gb18030, my_ismbchar_gb18030}, { 254, UTF8_MB3, UTF8_MB3"_general_cs", 1, 3, "", mysqlnd_mbcharlen_utf8, check_mb_utf8_valid}, { 0, NULL, NULL, 0, 0, NULL, NULL, NULL} diff --git a/ext/oci8/LICENSE b/ext/oci8/LICENSE index 42536af320..6059c80e12 100644 --- a/ext/oci8/LICENSE +++ b/ext/oci8/LICENSE @@ -1,6 +1,6 @@ -------------------------------------------------------------------- The PHP License, version 3.01 -Copyright (c) 1999 - 2012 The PHP Group. All rights reserved. +Copyright (c) 1999 - 2014 The PHP Group. All rights reserved. -------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index 577d1b6609..30705ff18a 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -25,6 +25,9 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { case ZEND_MUL: case ZEND_DIV: case ZEND_MOD: +#if ZEND_EXTENSION_API_NO >= PHP_5_6_X_API_NO + case ZEND_POW: +#endif case ZEND_SL: case ZEND_SR: case ZEND_CONCAT: diff --git a/ext/opcache/Optimizer/pass3.c b/ext/opcache/Optimizer/pass3.c index fd2a190009..1ee641ca52 100644 --- a/ext/opcache/Optimizer/pass3.c +++ b/ext/opcache/Optimizer/pass3.c @@ -45,6 +45,9 @@ if (ZEND_OPTIMIZER_PASS_3 & OPTIMIZATION_LEVEL) { case ZEND_MUL: case ZEND_DIV: case ZEND_MOD: +#if ZEND_EXTENSION_API_NO >= PHP_5_6_X_API_NO + case ZEND_POW: +#endif case ZEND_CONCAT: case ZEND_SL: case ZEND_SR: @@ -104,6 +107,11 @@ if (ZEND_OPTIMIZER_PASS_3 & OPTIMIZATION_LEVEL) { case ZEND_MOD: opline->opcode = ZEND_ASSIGN_MOD; break; +#if ZEND_EXTENSION_API_NO >= PHP_5_6_X_API_NO + case ZEND_POW: + opline->opcode = ZEND_ASSIGN_POW; + break; +#endif case ZEND_CONCAT: opline->opcode = ZEND_ASSIGN_CONCAT; break; diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 973ba3aaac..fc7d0a29b3 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -367,20 +367,41 @@ static void replace_tmp_by_const(zend_op_array *op_array, 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; + /* In most cases IS_TMP_VAR operand may be used only once. + * The operands are usually destroyed by the opcode handler. + * ZEND_CASE is an exception, that keeps operand unchanged, + * and allows its reuse. The number of ZEND_CASE instructions + * usually terminated by ZEND_FREE that finally kills the value. + */ + if (opline->opcode == ZEND_CASE) { + zval old_val; + old_val = *val; + zval_copy_ctor(val); + update_op1_const(op_array, opline, val TSRMLS_CC); + *val = old_val; + } else if (opline->opcode == ZEND_FREE) { + MAKE_NOP(opline); + break; + } else { + update_op1_const(op_array, opline, val TSRMLS_CC); + val = NULL; + 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 */ + /* TMP_VAR may be used only once */ + val = NULL; break; } opline++; } + if (val) { + zval_dtor(val); + } } #include "Optimizer/nop_removal.c" diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 6479a6ff40..a25e766244 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -93,7 +93,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 +#define PHP_5_6_X_API_NO 220131226 /*** file locking ***/ #ifndef ZEND_WIN32 diff --git a/ext/opcache/tests/bug67215.phpt b/ext/opcache/tests/bug67215.phpt new file mode 100644 index 0000000000..e9919d1001 --- /dev/null +++ b/ext/opcache/tests/bug67215.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #67215 (php-cgi work with opcache, may be segmentation fault happen) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$file_c = __DIR__ . "/bug67215.c.php"; +$file_p = __DIR__ . "/bug67215.p.php"; +file_put_contents($file_c, "<?php require \"$file_p\"; class c extends p {} ?>"); +file_put_contents($file_p, '<?php class p { protected $var = ""; } ?>'); +require $file_c; +$a = new c(); +require $file_c; +?> +--CLEAN-- +<?php +$file_c = __DIR__ . "/bug67215.c.php"; +$file_p = __DIR__ . "/bug67215.p.php"; +unlink($file_c); +unlink($file_p); +?> +--EXPECTF-- +Fatal error: Cannot redeclare class c in %sbug67215.c.php on line %d diff --git a/ext/opcache/tests/issue0183.phpt b/ext/opcache/tests/issue0183.phpt new file mode 100644 index 0000000000..9e18f6d2e8 --- /dev/null +++ b/ext/opcache/tests/issue0183.phpt @@ -0,0 +1,25 @@ +--TEST-- +ISSUE #183 (TMP_VAR is not only used once) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +<?php if (PHP_OS != "Linux") die("skip, only for linux"); ?> +--FILE-- +<?php + +switch (PHP_OS) { + case "Windows": + break; + case "Darwin": + break; + case "Linux": + echo "okey"; + break; + default: + break; +} +--EXPECT-- +okey diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index ae33e765ca..33103e54d1 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -899,16 +899,11 @@ static int zend_hash_unique_copy(HashTable *target, HashTable *source, unique_co if (p->nKeyLength > 0 && p->arKey[0] == 0) { /* 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); - } + 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; diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 17f8e8798f..fdc21d6c5d 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -686,6 +686,12 @@ static int zend_update_parent_ce(zend_class_entry **pce TSRMLS_DC) ce->__callstatic->op_array.refcount++; } #endif +#if ZEND_EXTENSION_API_NO >= PHP_5_6_X_API_NO + if (ce->__debugInfo) { + ce->__debugInfo = zend_shared_alloc_get_xlat_entry(ce->__debugInfo); + ce->__debugInfo->op_array.refcount++; + } +#endif zend_hash_apply(&ce->properties_info, (apply_func_t) zend_update_property_info_ce TSRMLS_CC); return 0; } diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 4f8f4b7334..118dcd99c2 100755 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -708,7 +708,7 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */ char * thestr; long gmadjust = 0; - if (ASN1_STRING_type(timestr) != V_ASN1_UTCTIME) { + if (ASN1_STRING_type(timestr) != V_ASN1_UTCTIME && ASN1_STRING_type(timestr) != V_ASN1_GENERALIZEDTIME) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal ASN1 data type for timestamp"); return (time_t)-1; } @@ -723,6 +723,11 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */ return (time_t)-1; } + if (ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME && ASN1_STRING_length(timestr) < 15) { + 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)); @@ -744,14 +749,21 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */ *thestr = '\0'; thestr -= 2; thetime.tm_mon = atoi(thestr)-1; + *thestr = '\0'; - thestr -= 2; - thetime.tm_year = atoi(thestr); + if( ASN1_STRING_type(timestr) == V_ASN1_UTCTIME ) { + thestr -= 2; + thetime.tm_year = atoi(thestr); - if (thetime.tm_year < 68) { - thetime.tm_year += 100; + if (thetime.tm_year < 68) { + thetime.tm_year += 100; + } + } else if( ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME ) { + thestr -= 4; + thetime.tm_year = atoi(thestr) - 1900; } + thetime.tm_isdst = -1; ret = mktime(&thetime); diff --git a/ext/openssl/tests/bug65538_002.phpt b/ext/openssl/tests/bug65538_002.phpt index dfc6f94ff7..1066e01e54 100644 --- a/ext/openssl/tests/bug65538_002.phpt +++ b/ext/openssl/tests/bug65538_002.phpt @@ -3,6 +3,7 @@ Bug #65538: SSL context "cafile" disallows URL stream wrappers --SKIPIF-- <?php if (!extension_loaded('openssl')) die('skip, openssl required'); +if (getenv("SKIP_ONLINE_TESTS")) die("skip online test"); --FILE-- <?php $clientCtx = stream_context_create(['ssl' => [ diff --git a/ext/openssl/tests/bug65698.crt b/ext/openssl/tests/bug65698.crt new file mode 100644 index 0000000000..c4a0261138 --- /dev/null +++ b/ext/openssl/tests/bug65698.crt @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEsTCCA5mgAwIBAgIQdwrGwrpRpBwdXS+ZsmsMGjANBgkqhkiG9w0BAQUFADA+ +MQswCQYDVQQGEwJQTDEbMBkGA1UEChMSVW5pemV0byBTcC4geiBvLm8uMRIwEAYD +VQQDEwlDZXJ0dW0gQ0EwIhgPMjAwOTAzMDMxMjUzMThaGA8yMDI0MDMwMzEyNTMx +OFowdzELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVz +IFMuQS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEb +MBkGA1UEAxMSQ2VydHVtIExldmVsIElJIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4LE0Ixw8h5Lper9tHVtZkWIujxYsPVgUZABeZZgQsKTdJjaG +VP64B/oiEV5Hd3AxRqaZ7dRRsf4Pg/PSS/2mHRQQ/SH3XACbrDHmucDvYgtU/WoZ +yp9d6PXVPY4j7J5t/52s+EbZD5swSuQLGjZ9iwg9sXX3JdJ9Ty+B3z80oiajpK0B +wqAxrcX3DekEOknj7LkAOK6iuQKI85REj4IVb9kD7KKIWdISGbfL4Ezh/TP51e0L +/WhTJ7lHbHbRzFfPU/oi3Qyt5tEexrPKe+6N+Jrejdb5Ya7Ne3tKujDU7KlbO+dn +pzFH7VHkBPJcQJ7QUrprPaqVsVg3JJ1PXTqVnwIDAQABo4IBbDCCAWgwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUgGIR3sBrpxDhCPBVtDCDv/qPCGAwUgYDVR0j +BEswSaFCpEAwPjELMAkGA1UEBhMCUEwxGzAZBgNVBAoTElVuaXpldG8gU3AuIHog +by5vLjESMBAGA1UEAxMJQ2VydHVtIENBggMBACAwDgYDVR0PAQH/BAQDAgEGMCwG +A1UdHwQlMCMwIaAfoB2GG2h0dHA6Ly9jcmwuY2VydHVtLnBsL2NhLmNybDBoBggr +BgEFBQcBAQRcMFowKAYIKwYBBQUHMAGGHGh0dHA6Ly9zdWJjYS5vY3NwLWNlcnR1 +bS5jb20wLgYIKwYBBQUHMAKGImh0dHA6Ly9yZXBvc2l0b3J5LmNlcnR1bS5wbC9j +YS5jZXIwOgYDVR0gBDMwMTAvBgRVHSAAMCcwJQYIKwYBBQUHAgEWGWh0dHBzOi8v +d3d3LmNlcnR1bS5wbC9DUFMwDQYJKoZIhvcNAQEFBQADggEBAI/jSDAW/w9qLzF6 +4oQiIRB7dGKp2Nlj27xZFYDBRINn4DKyZExkpanASF2of9eEzvrS+qoDY29mhXCi +MkiGr0vCsVhn0ReUpjg4Z5SsiQhZ2BGSjXiOJgaDI7Dw1MH7Ru6jdfSbLyd97EFj +ER0ERGdrcA2kLw7KfQm78IkClXEEKjKnAUTn1d/5Y4UuBWDCEL0FLgO9AqNXEzIy +rlXVGIs73kdefAK+Z1T6dm83vUrDMyzemWNRBI2tVBujkN6zkaF6uPjE4hfoIkEQ +Z4317byFkG4mxjATU+tQLG1Bs88HUAOrxtJOo/WoeCNsFJaxbYPt4oQGxIVYdz29 +OUX9CQA= +-----END CERTIFICATE----- diff --git a/ext/openssl/tests/bug65698.phpt b/ext/openssl/tests/bug65698.phpt new file mode 100644 index 0000000000..35d31764d5 --- /dev/null +++ b/ext/openssl/tests/bug65698.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #65689 (GeneralizedTime format parsing) +--SKIPIF-- +<?php +if (!extension_loaded("openssl")) die("skip"); +?> +--FILE-- +<?php +$crt = substr(__FILE__, 0, -4).'.crt'; +$info = openssl_x509_parse("file://$crt"); +var_dump($info["validFrom"], $info["validFrom_time_t"], $info["validTo"], $info["validTo_time_t"]); +?> +Done +--EXPECTF-- +string(15) "20090303125318Z" +int(1236084798) +string(15) "20240303125318Z" +int(1709470398) +Done diff --git a/ext/openssl/tests/cve-2013-6420.phpt b/ext/openssl/tests/cve-2013-6420.phpt index 87c0210b2e..ccead0aab6 100644 --- a/ext/openssl/tests/cve-2013-6420.phpt +++ b/ext/openssl/tests/cve-2013-6420.phpt @@ -12,7 +12,7 @@ var_dump($info['issuer']['emailAddress'], $info["validFrom_time_t"]); ?> Done --EXPECTF-- -%s openssl_x509_parse(): illegal ASN1 data type for timestamp in %s%ecve-2013-6420.php on line 3 +%s openssl_x509_parse(): illegal length in 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_spki_verify.phpt b/ext/openssl/tests/openssl_spki_verify.phpt index 1ee573fd3f..52dc8e2045 100644 --- a/ext/openssl/tests/openssl_spki_verify.phpt +++ b/ext/openssl/tests/openssl_spki_verify.phpt @@ -17,9 +17,7 @@ $ksize = array('1024'=>1024, '4096'=>4096); /* array of available hashings to test */ -$algo = array('md4'=>OPENSSL_ALGO_MD4, - 'md5'=>OPENSSL_ALGO_MD5, - 'sha1'=>OPENSSL_ALGO_SHA1, +$algo = array('sha1'=>OPENSSL_ALGO_SHA1, 'sha224'=>OPENSSL_ALGO_SHA224, 'sha256'=>OPENSSL_ALGO_SHA256, 'sha384'=>OPENSSL_ALGO_SHA384, @@ -90,16 +88,4 @@ bool(false) bool(true) bool(false) bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) bool(false)
\ No newline at end of file diff --git a/ext/pcre/pcrelib/pcre_compile.c b/ext/pcre/pcrelib/pcre_compile.c index c170c47a00..853fb24793 100644 --- a/ext/pcre/pcrelib/pcre_compile.c +++ b/ext/pcre/pcrelib/pcre_compile.c @@ -3623,7 +3623,7 @@ for (;;) break; case OP_MINUPTO: - *code += OP_MINUPTO - OP_UPTO; + *code += OP_POSUPTO - OP_MINUPTO; break; } } diff --git a/ext/pcre/tests/bug67238.phpt b/ext/pcre/tests/bug67238.phpt new file mode 100644 index 0000000000..117662af6b --- /dev/null +++ b/ext/pcre/tests/bug67238.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #67238 Ungreedy and min/max quantifier bug in PCRE 8.34 upstream +--FILE-- +<?php + +echo preg_match('/a{1,3}b/U', 'ab'); + +?> +--EXPECTF-- +1 diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index fa8ef187fa..9f6a6a7365 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 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 | diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 2053a07005..1327861fe9 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -567,7 +567,7 @@ static int firebird_handle_get_attribute(pdo_dbh_t *dbh, long attr, zval *val TS #else HMODULE l = GetModuleHandle("fbclient"); - if (!l && !(l = GetModuleHandle("gds32"))) { + if (!l) { break; } info_func = (info_func_t)GetProcAddress(l, "isc_get_client_version"); @@ -575,9 +575,7 @@ static int firebird_handle_get_attribute(pdo_dbh_t *dbh, long attr, zval *val TS if (info_func) { info_func(tmp); ZVAL_STRING(val,tmp,1); - } else { - ZVAL_STRING(val,"Firebird 1.0/Interbase 6",1); - } + } #else ZVAL_NULL(val); #endif diff --git a/ext/pdo_firebird/pdo_firebird.c b/ext/pdo_firebird/pdo_firebird.c index 595a6a3987..d59aa53fa3 100644 --- a/ext/pdo_firebird/pdo_firebird.c +++ b/ext/pdo_firebird/pdo_firebird.c @@ -35,21 +35,15 @@ const zend_function_entry pdo_firebird_functions[] = { /* {{{ */ /* {{{ pdo_firebird_deps */ -#if ZEND_MODULE_API_NO >= 20050922 static const zend_module_dep pdo_firebird_deps[] = { ZEND_MOD_REQUIRED("pdo") ZEND_MOD_END }; -#endif /* }}} */ zend_module_entry pdo_firebird_module_entry = { /* {{{ */ -#if ZEND_MODULE_API_NO >= 20050922 STANDARD_MODULE_HEADER_EX, NULL, pdo_firebird_deps, -#else - STANDARD_MODULE_HEADER, -#endif "PDO_Firebird", pdo_firebird_functions, PHP_MINIT(pdo_firebird), diff --git a/ext/pdo_mysql/tests/bug54929.phpt b/ext/pdo_mysql/tests/bug54929.phpt index 29fb44182b..84b9e7d04f 100644 --- a/ext/pdo_mysql/tests/bug54929.phpt +++ b/ext/pdo_mysql/tests/bug54929.phpt @@ -47,14 +47,14 @@ array(1) { string(3) "foo" } -Warning: PDOStatement::execute(): 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 '--'' at line 1 in %s on line %d +Warning: PDOStatement::execute(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near '--'' at line 1 in %s on line %d array(3) { [0]=> string(5) "42000" [1]=> int(1064) [2]=> - string(149) "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 '--'' at line 1" + string(149) "You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near '--'' at line 1" } array(1) { ["f1"]=> diff --git a/ext/pdo_mysql/tests/bug66141.phpt b/ext/pdo_mysql/tests/bug66141.phpt index 3a28509314..5c382dfe0e 100644 --- a/ext/pdo_mysql/tests/bug66141.phpt +++ b/ext/pdo_mysql/tests/bug66141.phpt @@ -31,7 +31,7 @@ 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 +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 %s 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'" diff --git a/ext/pdo_mysql/tests/pdo_mysql_attr_errmode.phpt b/ext/pdo_mysql/tests/pdo_mysql_attr_errmode.phpt index b03708900f..ce6a1ecd26 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_attr_errmode.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_attr_errmode.phpt @@ -161,6 +161,6 @@ error_reporting=E_ALL --EXPECTF-- [003] Maybe PDO could indicate that this is not a proper way of setting the ERRMODE...true -Warning: PDO::query(): SQLSTATE[42000]: Syntax error or access violation: %d 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 '%s' at line %d in %s on line %d +Warning: PDO::query(): SQLSTATE[42000]: Syntax error or access violation: %d You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near '%s' at line %d in %s on line %d end of execution
\ No newline at end of file diff --git a/ext/pdo_mysql/tests/pdo_mysql_exec.phpt b/ext/pdo_mysql/tests/pdo_mysql_exec.phpt index 2a0f527180..acd90904f7 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_exec.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_exec.phpt @@ -179,7 +179,7 @@ $db = MySQLPDOTest::factory(); @$db->exec('DROP TABLE IF EXISTS test'); ?> --EXPECTF-- -Warning: PDO::exec(): 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 'THIS IS NOT VALID SQL, I HOPE' at line 1 in %s on line %d -[016] [42000] 42000 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 'THIS IS NOT VALID SQL, I HOPE' at line %d +Warning: PDO::exec(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'THIS IS NOT VALID SQL, I HOPE' at line 1 in %s on line %d +[016] [42000] 42000 1064 You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'THIS IS NOT VALID SQL, I HOPE' at line %d [035] With emulated PS it works but makes no sense given that exec() returns sort of affected rows... done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_multiquery.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_multiquery.phpt index 37aa903dfa..a95209c434 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_multiquery.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_multiquery.phpt @@ -97,6 +97,6 @@ array(1) { } Native Prepared Statements... -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 '%SSELECT label FROM test ORDER BY id ASC LIMIT 1' at line %d in %s on line %d +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 %s server version for the right syntax to use near '%SSELECT label FROM test ORDER BY id ASC LIMIT 1' at line %d in %s on line %d -Catchable fatal error: Call to a member function errorInfo() on a non-object in %s on line %d +Catchable fatal error: Call to a member function errorInfo() on a non-object in %s on line %d
\ No newline at end of file diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c index 8b0ccf34e6..1d275cd654 100644 --- a/ext/pdo_odbc/odbc_stmt.c +++ b/ext/pdo_odbc/odbc_stmt.c @@ -279,7 +279,7 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data; RETCODE rc; SWORD sqltype = 0, ctype = 0, scale = 0, nullable = 0; - UDWORD precision = 0; + SQLULEN precision = 0; pdo_odbc_param *P; /* we're only interested in parameters for prepared SQL right now */ @@ -551,7 +551,7 @@ static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) struct pdo_column_data *col = &stmt->columns[colno]; RETCODE rc; SWORD colnamelen; - SDWORD colsize; + SQLULEN colsize; SQLLEN displaysize; rc = SQLDescribeCol(S->stmt, colno+1, S->cols[colno].colname, diff --git a/ext/pdo_odbc/php_pdo_odbc_int.h b/ext/pdo_odbc/php_pdo_odbc_int.h index 87b2f9100d..5e42951f86 100644 --- a/ext/pdo_odbc/php_pdo_odbc_int.h +++ b/ext/pdo_odbc/php_pdo_odbc_int.h @@ -157,7 +157,7 @@ typedef struct { } pdo_odbc_stmt; typedef struct { - SQLINTEGER len; + SQLLEN len; SQLSMALLINT paramtype; char *outbuf; unsigned is_unicode:1; diff --git a/ext/pdo_pgsql/tests/bug62479.phpt b/ext/pdo_pgsql/tests/bug62479.phpt index a12bb8d1ff..913321828e 100644 --- a/ext/pdo_pgsql/tests/bug62479.phpt +++ b/ext/pdo_pgsql/tests/bug62479.phpt @@ -6,15 +6,34 @@ if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not lo require dirname(__FILE__) . '/config.inc'; require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc'; PDOTest::skip(); -if (!isset($conf['ENV']['PDOTEST_DSN'])) die('no dsn found in env'); + +$dsn = getenv('PDOTEST_DSN'); +if (empty($dsn)) die('skip no dsn found in env'); + $db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt'); -$rand = rand(5, 5); +$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + +$user = 'pdo_test_'.rand(5, 400); +$pass = 'testpass'; + +// Assume that if we can't create or drop a user, this test needs to be skipped +try { + $db->exec("DROP USER IF EXISTS $user"); + $db->exec("CREATE USER $user WITH PASSWORD '$pass'"); +} catch (PDOException $e) { + die("skip You need CREATEUSER permissions to run the test"); +} + +// Peer authentication might prevent the test from properly running +try { + $testConn = new PDO($dsn, $user, $pass); +} catch (PDOException $e) { + echo "skip ".$e->getMessage(); +} + +$db->exec("DROP USER $user"); -// Assume that if we can't create a user, this test needs to be skipped -$testQuery = "CREATE USER pdo_$rand WITH PASSWORD 'testpass'"; -$db->query($testQuery); -$testQuery = "DROP USER pdo_$rand"; -$db->query($testQuery); ?> --FILE-- <?php @@ -22,7 +41,7 @@ require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc'; $pdo = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt'); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); $rand = rand(5, 400); -$user = "pdo_$rand"; +$user = "pdo_test_$rand"; $template = "CREATE USER $user WITH PASSWORD '%s'"; $dropUser = "DROP USER $user"; $testQuery = 'SELECT 1 as verification'; diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index d867f433b2..6a433af0f3 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -783,7 +783,7 @@ static int le_link, le_plink, le_result, le_lofp, le_string; #endif #if !HAVE_PQESCAPE_CONN -#define PQescapeStringConn(conn, to, form, len, error) PQescapeString(to, from, len) +#define PQescapeStringConn(conn, to, from, len, error) PQescapeString(to, from, len) #endif #if HAVE_PQESCAPELITERAL @@ -1127,7 +1127,9 @@ PHP_MINIT_FUNCTION(pgsql) REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_MADE", CONNECTION_MADE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_AWAITING_RESPONSE", CONNECTION_AWAITING_RESPONSE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_AUTH_OK", CONNECTION_AUTH_OK, CONST_CS | CONST_PERSISTENT); +#ifdef CONNECTION_SSL_STARTUP REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_SSL_STARTUP", CONNECTION_SSL_STARTUP, CONST_CS | CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_SETENV", CONNECTION_SETENV, CONST_CS | CONST_PERSISTENT); /* For pg_connect_poll() */ REGISTER_LONG_CONSTANT("PGSQL_POLLING_FAILED", PGRES_POLLING_FAILED, CONST_CS | CONST_PERSISTENT); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 407edda0fb..75aadfbc54 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -1477,7 +1477,7 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ } close_fp = 0; - opened = (char *) estrndup(str, sizeof("[stream]") + 1); + opened = (char *) estrndup(str, sizeof("[stream]") - 1); goto after_open_fp; case IS_OBJECT: if (instanceof_function(Z_OBJCE_PP(value), spl_ce_SplFileInfo TSRMLS_CC)) { diff --git a/ext/phar/phar_path_check.c b/ext/phar/phar_path_check.c index db97efcbe3..ebf4aac58b 100644 --- a/ext/phar/phar_path_check.c +++ b/ext/phar/phar_path_check.c @@ -46,60 +46,91 @@ loop: #line 47 "ext/phar/phar_path_check.c" { YYCTYPE yych; + unsigned int yyaccept = 0; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; - if (yych <= '.') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy13; - if (yych <= '\t') goto yy10; - goto yy12; + if (yych <= '[') { + if (yych <= ')') { + if (yych <= '\t') { + if (yych <= 0x00) goto yy21; + goto yy23; + } else { + if (yych <= '\n') goto yy2; + if (yych <= 0x19) goto yy23; + goto yy11; + } } else { - if (yych <= 0x19) goto yy10; - if (yych == '*') goto yy6; - goto yy15; + if (yych <= '/') { + if (yych <= '*') goto yy7; + if (yych <= '.') goto yy11; + goto yy3; + } else { + if (yych == '?') goto yy9; + goto yy11; + } } } else { - if (yych <= '?') { - if (yych <= '/') goto yy2; - if (yych <= '>') goto yy15; - goto yy8; + if (yych <= 0xEC) { + if (yych <= 0xC1) { + if (yych <= '\\') goto yy5; + if (yych <= 0x7F) goto yy11; + goto yy23; + } else { + if (yych <= 0xDF) goto yy12; + if (yych <= 0xE0) goto yy14; + goto yy15; + } } else { - if (yych == '\\') goto yy4; - if (yych <= 0x7F) goto yy15; - goto yy10; + if (yych <= 0xF0) { + if (yych <= 0xED) goto yy16; + if (yych <= 0xEF) goto yy17; + goto yy18; + } else { + if (yych <= 0xF3) goto yy19; + if (yych <= 0xF4) goto yy20; + goto yy23; + } } } yy2: - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '-') goto yy3; - if (yych <= '.') goto yy16; - if (yych <= '/') goto yy18; + YYCURSOR = YYMARKER; + if (yyaccept <= 0) { + goto yy4; + } else { + goto yy13; + } yy3: -#line 93 "ext/phar/phar_path_check.re" + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '-') goto yy4; + if (yych <= '.') goto yy35; + if (yych <= '/') goto yy36; +yy4: +#line 88 "ext/phar/phar_path_check.re" { goto loop; } -#line 84 "ext/phar/phar_path_check.c" -yy4: +#line 115 "ext/phar/phar_path_check.c" +yy5: ++YYCURSOR; -#line 60 "ext/phar/phar_path_check.re" +#line 72 "ext/phar/phar_path_check.re" { *error = "back-slash"; return pcr_err_back_slash; } -#line 92 "ext/phar/phar_path_check.c" -yy6: +#line 123 "ext/phar/phar_path_check.c" +yy7: ++YYCURSOR; -#line 64 "ext/phar/phar_path_check.re" +#line 76 "ext/phar/phar_path_check.re" { *error = "star"; return pcr_err_star; } -#line 100 "ext/phar/phar_path_check.c" -yy8: +#line 131 "ext/phar/phar_path_check.c" +yy9: ++YYCURSOR; -#line 68 "ext/phar/phar_path_check.re" +#line 80 "ext/phar/phar_path_check.re" { if (**s == '/') { (*s)++; @@ -108,22 +139,66 @@ yy8: *error = NULL; return pcr_use_query; } -#line 112 "ext/phar/phar_path_check.c" -yy10: - ++YYCURSOR; +#line 143 "ext/phar/phar_path_check.c" yy11: -#line 76 "ext/phar/phar_path_check.re" + yych = *++YYCURSOR; + goto yy4; +yy12: + ++YYCURSOR; + if ((yych = *YYCURSOR) <= 0x7F) goto yy13; + if (yych <= 0xBF) goto yy26; +yy13: +#line 104 "ext/phar/phar_path_check.re" { *error ="illegal character"; return pcr_err_illegal_char; } -#line 121 "ext/phar/phar_path_check.c" -yy12: - yych = *++YYCURSOR; - goto yy11; -yy13: +#line 157 "ext/phar/phar_path_check.c" +yy14: + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x9F) goto yy13; + if (yych <= 0xBF) goto yy34; + goto yy13; +yy15: + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x7F) goto yy13; + if (yych <= 0xBF) goto yy33; + goto yy13; +yy16: + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x7F) goto yy13; + if (yych <= 0x9F) goto yy32; + goto yy13; +yy17: + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x7F) goto yy13; + if (yych <= 0xBF) goto yy31; + goto yy13; +yy18: + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x8F) goto yy13; + if (yych <= 0xBF) goto yy29; + goto yy13; +yy19: + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x7F) goto yy13; + if (yych <= 0xBF) goto yy27; + goto yy13; +yy20: + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x7F) goto yy13; + if (yych <= 0x8F) goto yy24; + goto yy13; +yy21: ++YYCURSOR; -#line 80 "ext/phar/phar_path_check.re" +#line 91 "ext/phar/phar_path_check.re" { if (**s == '/') { (*s)++; @@ -137,49 +212,93 @@ yy13: *error = NULL; return pcr_is_ok; } -#line 141 "ext/phar/phar_path_check.c" -yy15: +#line 216 "ext/phar/phar_path_check.c" +yy23: yych = *++YYCURSOR; - goto yy3; -yy16: + goto yy13; +yy24: yych = *++YYCURSOR; - if (yych <= 0x00) goto yy21; - if (yych <= '-') goto yy17; - if (yych <= '.') goto yy20; - if (yych <= '/') goto yy21; -yy17: - YYCURSOR = YYMARKER; - goto yy3; -yy18: + if (yych <= 0x7F) goto yy2; + if (yych >= 0xC0) goto yy2; + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy2; + if (yych >= 0xC0) goto yy2; +yy26: + yych = *++YYCURSOR; + goto yy4; +yy27: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy2; + if (yych >= 0xC0) goto yy2; + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy2; + if (yych <= 0xBF) goto yy26; + goto yy2; +yy29: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy2; + if (yych >= 0xC0) goto yy2; + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy2; + if (yych <= 0xBF) goto yy26; + goto yy2; +yy31: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy2; + if (yych <= 0xBF) goto yy26; + goto yy2; +yy32: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy2; + if (yych <= 0xBF) goto yy26; + goto yy2; +yy33: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy2; + if (yych <= 0xBF) goto yy26; + goto yy2; +yy34: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy2; + if (yych <= 0xBF) goto yy26; + goto yy2; +yy35: + yych = *++YYCURSOR; + if (yych <= 0x00) goto yy39; + if (yych <= '-') goto yy2; + if (yych <= '.') goto yy38; + if (yych <= '/') goto yy39; + goto yy2; +yy36: ++YYCURSOR; -#line 48 "ext/phar/phar_path_check.re" +#line 60 "ext/phar/phar_path_check.re" { *error = "double slash"; return pcr_err_double_slash; } -#line 161 "ext/phar/phar_path_check.c" -yy20: +#line 280 "ext/phar/phar_path_check.c" +yy38: yych = *++YYCURSOR; - if (yych <= 0x00) goto yy23; - if (yych == '/') goto yy23; - goto yy17; -yy21: + if (yych <= 0x00) goto yy41; + if (yych == '/') goto yy41; + goto yy2; +yy39: ++YYCURSOR; -#line 56 "ext/phar/phar_path_check.re" +#line 68 "ext/phar/phar_path_check.re" { *error = "current directory reference"; return pcr_err_curr_dir; } -#line 174 "ext/phar/phar_path_check.c" -yy23: +#line 293 "ext/phar/phar_path_check.c" +yy41: ++YYCURSOR; -#line 52 "ext/phar/phar_path_check.re" +#line 64 "ext/phar/phar_path_check.re" { *error = "upper directory reference"; return pcr_err_up_dir; } -#line 182 "ext/phar/phar_path_check.c" +#line 301 "ext/phar/phar_path_check.c" } -#line 96 "ext/phar/phar_path_check.re" +#line 108 "ext/phar/phar_path_check.re" } diff --git a/ext/phar/phar_path_check.re b/ext/phar/phar_path_check.re index e43b3f846e..df64076871 100644 --- a/ext/phar/phar_path_check.re +++ b/ext/phar/phar_path_check.re @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) 2007-2013 The PHP Group | + | Copyright (c) 2007-2014 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 | @@ -42,7 +42,19 @@ phar_path_check_result phar_path_check(char **s, int *len, const char **error) loop: /*!re2c END = "\x00"; -ILL = [\x01-\x19\x80-\xFF]; +UTF8T = [\x80-\xBF] ; +UTF8_1 = [\x1A-\x7F] ; +UTF8_2 = [\xC2-\xDF] UTF8T ; +UTF8_3A = "\xE0" [\xA0-\xBF] UTF8T ; +UTF8_3B = [\xE1-\xEC] UTF8T{2} ; +UTF8_3C = "\xED" [\x80-\x9F] UTF8T ; +UTF8_3D = [\xEE-\xEF] UTF8T{2} ; +UTF8_3 = UTF8_3A | UTF8_3B | UTF8_3C | UTF8_3D ; +UTF8_4A = "\xF0"[\x90-\xBF] UTF8T{2} ; +UTF8_4B = [\xF1-\xF3] UTF8T{3} ; +UTF8_4C = "\xF4" [\x80-\x8F] UTF8T{2} ; +UTF8_4 = UTF8_4A | UTF8_4B | UTF8_4C ; +UTF8 = UTF8_1 | UTF8_2 | UTF8_3 | UTF8_4 ; EOS = "/" | END; ANY = .; "//" { @@ -73,9 +85,8 @@ ANY = .; *error = NULL; return pcr_use_query; } -ILL { - *error ="illegal character"; - return pcr_err_illegal_char; +UTF8 { + goto loop; } END { if (**s == '/') { @@ -91,7 +102,8 @@ END { return pcr_is_ok; } ANY { - goto loop; + *error ="illegal character"; + return pcr_err_illegal_char; } */ } diff --git a/ext/phar/tests/create_new_phar.phpt b/ext/phar/tests/create_new_phar.phpt index ec57c27217..26794095e1 100644 --- a/ext/phar/tests/create_new_phar.phpt +++ b/ext/phar/tests/create_new_phar.phpt @@ -9,8 +9,13 @@ phar.require_hash=1 <?php file_put_contents('phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/a.php', - 'brand new!'); + "brand new!\n"); include 'phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/a.php'; + +$fileName = "ChineseFile\xE5\x84\xB7\xE9\xBB\x91.php"; +file_put_contents('phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/$fileName.php', + 'Text in utf8 file.'); +include 'phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/$fileName.php'; ?> ===DONE=== @@ -18,4 +23,5 @@ include 'phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.pha <?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?> --EXPECT-- brand new! +Text in utf8 file. ===DONE=== diff --git a/ext/phar/tests/create_path_error.phpt b/ext/phar/tests/create_path_error.phpt index d3fc035860..886ba81925 100644 --- a/ext/phar/tests/create_path_error.phpt +++ b/ext/phar/tests/create_path_error.phpt @@ -22,15 +22,28 @@ var_dump(file_get_contents($pname . '/b.php')); function error_handler($errno, $errmsg) { - echo "Error: $errmsg\n"; + echo "Error: $errmsg"; } set_error_handler('error_handler'); -$checks = array('/', '.', '../', 'a/..', 'a/', 'b//a.php'); +$count = 0; +$checks = array( + '/', '.', '../', 'a/..', 'a/', 'b//a.php', + "Font\xE5\x84\xB7\xE9\xBB\x91pro.ttf", //two valid multi-byte characters + "\xF0\x9F\x98\x8D.ttf", // valid 4 byte char - smiling face with heart-shaped eyes + "Font\xE9\xBBpro.ttf", //Invalid multi-byte character - missing last byte + "Font\xBB\x91pro.ttf", //Invalid multi-byte character - missing first byte + "Font\xC0\xAFpro.ttf", //Invalid multi-byte character - invalid first byte + "Font\xF0\x80\x90\x90pro.ttf", //Invalid multi-byte character - surrogate pair code point + "\xFC\x81\x81\x81\x81pro.ttf", //RFC 3629 limited char points to 0000-10FFFF aka 5 byte utf-8 not valid +); foreach($checks as $check) { + $count++; + echo "$count:"; file_put_contents($pname . '/' . $check, "error"); + echo "\n"; } $phar = new Phar($fname); @@ -54,9 +67,19 @@ foreach($checks as $check) --EXPECTF-- string(5) "query" string(5) "query" -Error: file_put_contents(phar://%s//): failed to open stream: phar error: file "" in phar "%s" cannot be empty -Error: file_put_contents(phar://%s/.): failed to open stream: phar error: file "" in phar "%s" cannot be empty -Error: file_put_contents(phar://%s/../): failed to open stream: phar error: file "" in phar "%s" cannot be empty -Error: file_put_contents(phar://%s/a/..): failed to open stream: phar error: file "" in phar "%s" cannot be empty +1:Error: file_put_contents(phar://%s//): failed to open stream: phar error: file "" in phar "%s" cannot be empty +2:Error: file_put_contents(phar://%s/.): failed to open stream: phar error: file "" in phar "%s" cannot be empty +3:Error: file_put_contents(phar://%s/../): failed to open stream: phar error: file "" in phar "%s" cannot be empty +4:Error: file_put_contents(phar://%s/a/..): failed to open stream: phar error: file "" in phar "%s" cannot be empty +5: +6: +7: +8: +9:Error: file_put_contents(phar:///%s): failed to open stream: phar error: invalid path "%s" contains illegal character +10:Error: file_put_contents(phar:///%s): failed to open stream: phar error: invalid path "%s" contains illegal character +11:Error: file_put_contents(phar:///%s): failed to open stream: phar error: invalid path "%s" contains illegal character +12:Error: file_put_contents(phar:///%s): failed to open stream: phar error: invalid path "%s" contains illegal character +13:Error: file_put_contents(phar:///%s): failed to open stream: phar error: invalid path "%s" contains illegal character Exception: Entry a does not exist and cannot be created: phar error: invalid path "a" contains illegal character ===DONE=== + diff --git a/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt b/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt index eeaf8d382c..368464e130 100644 --- a/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt +++ b/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt @@ -13,6 +13,6 @@ if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION <?php $closure = function($param) { return "this is a closure"; }; $rc = new ReflectionFunction($closure); -echo var_dump($rc->isClosure()); +var_dump($rc->isClosure()); --EXPECTF-- bool(true) diff --git a/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt b/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt index 31d37a85f1..4148fada0c 100644 --- a/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt +++ b/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt @@ -10,6 +10,6 @@ if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION --FILE-- <?php $rc = new ReflectionFunction('ereg'); -echo var_dump($rc->isDeprecated()); +var_dump($rc->isDeprecated()); --EXPECTF-- bool(true) diff --git a/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt index c71b96b8ef..30189cf4de 100644 --- a/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt +++ b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt @@ -12,6 +12,6 @@ disable_functions=is_file --FILE-- <?php $rc = new ReflectionFunction('is_file'); -echo var_dump($rc->isDisabled()); +var_dump($rc->isDisabled()); --EXPECTF-- bool(true) diff --git a/ext/session/session.c b/ext/session/session.c index 1d60c40188..d6568bdbb5 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -51,6 +51,7 @@ #include "ext/standard/php_smart_str.h" #include "ext/standard/url.h" #include "ext/standard/basic_functions.h" +#include "ext/standard/head.h" #include "mod_files.h" #include "mod_user.h" @@ -1289,14 +1290,6 @@ static int php_session_cache_limiter(TSRMLS_D) /* {{{ */ * Cookie Management * ********************* */ -#define COOKIE_SET_COOKIE "Set-Cookie: " -#define COOKIE_EXPIRES "; expires=" -#define COOKIE_MAX_AGE "; Max-Age=" -#define COOKIE_PATH "; path=" -#define COOKIE_DOMAIN "; domain=" -#define COOKIE_SECURE "; secure" -#define COOKIE_HTTPONLY "; HttpOnly" - /* * Remove already sent session ID cookie. * It must be directly removed from SG(sapi_header) because sapi_add_header_ex() @@ -1362,7 +1355,7 @@ static void php_session_send_cookie(TSRMLS_D) /* {{{ */ e_session_name = php_url_encode(PS(session_name), strlen(PS(session_name)), NULL); e_id = php_url_encode(PS(id), strlen(PS(id)), NULL); - smart_str_appends(&ncookie, COOKIE_SET_COOKIE); + smart_str_appends(&ncookie, "Set-Cookie: "); smart_str_appends(&ncookie, e_session_name); smart_str_appendc(&ncookie, '='); smart_str_appends(&ncookie, e_id); @@ -1603,7 +1596,7 @@ PHPAPI void php_session_start(TSRMLS_D) /* {{{ */ } } - /* Finally check session id for dangarous characters + /* Finally check session id for dangerous characters * Security note: session id may be embedded in HTML pages.*/ if (PS(id) && strpbrk(PS(id), "\r\n\t <>'\"\\")) { efree(PS(id)); diff --git a/ext/session/tests/031.phpt b/ext/session/tests/031.phpt index e8deb3dac5..ba50247891 100644 --- a/ext/session/tests/031.phpt +++ b/ext/session/tests/031.phpt @@ -1,7 +1,13 @@ --TEST-- setting hash_function to sha512 and hash_bits_per_character > 4 should not crash --SKIPIF-- -<?php include('skipif.inc'); ?> +<?php +include('skipif.inc'); + +if (!function_exists("hash")) { + echo "skip hash extension not loaded"; +} +?> --INI-- session.use_cookies=0 session.cache_limiter= diff --git a/ext/session/tests/session_set_save_handler_class_005.phpt b/ext/session/tests/session_set_save_handler_class_005.phpt index a996eb8d26..c74c81de1d 100644 --- a/ext/session/tests/session_set_save_handler_class_005.phpt +++ b/ext/session/tests/session_set_save_handler_class_005.phpt @@ -3,6 +3,7 @@ Test session_set_save_handler() : incomplete implementation --INI-- session.save_handler=files session.name=PHPSESSID +session.gc_probability=0 --SKIPIF-- <?php include('skipif.inc'); ?> --FILE-- diff --git a/ext/session/tests/session_set_save_handler_class_012.phpt b/ext/session/tests/session_set_save_handler_class_012.phpt index 706ef793ef..3899d28816 100644 --- a/ext/session/tests/session_set_save_handler_class_012.phpt +++ b/ext/session/tests/session_set_save_handler_class_012.phpt @@ -3,6 +3,7 @@ Test session_set_save_handler() : incorrect arguments for existing handler open --INI-- session.save_handler=files session.name=PHPSESSID +session.gc_probability=0 --SKIPIF-- <?php include('skipif.inc'); ?> --FILE-- diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index f84e1e014d..a915862ec4 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1269,6 +1269,9 @@ SXE_METHOD(xpath) } if (!sxe->node) { php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement((xmlDocPtr) sxe->document->ptr), NULL TSRMLS_CC); + if (!sxe->node) { + RETURN_FALSE; + } } nodeptr = php_sxe_get_first_node(sxe, sxe->node->node TSRMLS_CC); @@ -1533,15 +1536,18 @@ SXE_METHOD(getDocNamespaces) return; } - array_init(return_value); - sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); if(from_root){ node = xmlDocGetRootElement((xmlDocPtr)sxe->document->ptr); }else{ GET_NODE(sxe, node); } - + + if (node == NULL) { + RETURN_FALSE; + } + + array_init(return_value); sxe_add_registered_namespaces(sxe, node, recursive, return_value TSRMLS_CC); } /* }}} */ diff --git a/ext/simplexml/tests/SimpleXMLElement_getDocNamespaces.phpt b/ext/simplexml/tests/SimpleXMLElement_getDocNamespaces.phpt new file mode 100644 index 0000000000..9df7591003 --- /dev/null +++ b/ext/simplexml/tests/SimpleXMLElement_getDocNamespaces.phpt @@ -0,0 +1,9 @@ +--TEST-- +Testing getDocNamespaces() with invalid XML +--FILE-- +<?php +$xml = @new SimpleXMLElement("X",1); +var_dump($xml->getDocNamespaces()); +?> +--EXPECTF-- +bool(false) diff --git a/ext/simplexml/tests/SimpleXMLElement_xpath.phpt b/ext/simplexml/tests/SimpleXMLElement_xpath.phpt new file mode 100644 index 0000000000..4a613c2e51 --- /dev/null +++ b/ext/simplexml/tests/SimpleXMLElement_xpath.phpt @@ -0,0 +1,8 @@ +--TEST-- +Testing xpath() with invalid XML +--FILE-- +<?php +$xml = @simplexml_load_string("XXXXXXX^",$x,0x6000000000000001); +var_dump($xml->xpath("BBBB")); +--EXPECT-- +bool(false) diff --git a/ext/soap/soap.c b/ext/soap/soap.c index a8c6cb9369..32bf5ca6f6 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -225,6 +225,7 @@ PHP_METHOD(SoapClient, __getFunctions); PHP_METHOD(SoapClient, __getTypes); PHP_METHOD(SoapClient, __doRequest); PHP_METHOD(SoapClient, __setCookie); +PHP_METHOD(SoapClient, __getCookies); PHP_METHOD(SoapClient, __setLocation); PHP_METHOD(SoapClient, __setSoapHeaders); @@ -368,6 +369,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___setcookie, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getcookies, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___setsoapheaders, 0, 0, 1) ZEND_ARG_INFO(0, soapheaders) ZEND_END_ARG_INFO() @@ -422,6 +426,7 @@ static const zend_function_entry soap_client_functions[] = { PHP_ME(SoapClient, __getTypes, arginfo_soapclient___gettypes, 0) PHP_ME(SoapClient, __doRequest, arginfo_soapclient___dorequest, 0) PHP_ME(SoapClient, __setCookie, arginfo_soapclient___setcookie, 0) + PHP_ME(SoapClient, __getCookies, arginfo_soapclient___getcookies, 0) PHP_ME(SoapClient, __setLocation, arginfo_soapclient___setlocation, 0) PHP_ME(SoapClient, __setSoapHeaders, arginfo_soapclient___setsoapheaders, 0) PHP_FE_END @@ -3150,6 +3155,24 @@ PHP_METHOD(SoapClient, __setCookie) } /* }}} */ +/* {{{ proto array SoapClient::__getCookies ( void ) + Returns list of cookies */ +PHP_METHOD(SoapClient, __getCookies) +{ + zval **cookies, *tmp; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + array_init(return_value); + + if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) != FAILURE) { + zend_hash_copy(Z_ARRVAL_P(return_value), Z_ARRVAL_P(*cookies), (copy_ctor_func_t) zval_add_ref, (void *)&tmp, sizeof(zval*)); + } +} +/* }}} */ + /* {{{ proto void SoapClient::__setSoapHeaders(array SoapHeaders) Sets SOAP headers for subsequent calls (replaces any previous values). diff --git a/ext/soap/tests/bug49898.phpt b/ext/soap/tests/bug49898.phpt new file mode 100644 index 0000000000..eea4ea490a --- /dev/null +++ b/ext/soap/tests/bug49898.phpt @@ -0,0 +1,14 @@ +--TEST-- +Test for bug #49898: SoapClient::__getCookies() implementation +--CREDITS-- +Boro Sitnikovski <buritomath@yahoo.com> +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$client = new SoapClient(null, array('uri' => 'mo:http://www.w3.org/', 'location' => 'http://some.url')); +$client->__setCookie("CookieTest", "HelloWorld"); +var_dump($client->__getCookies()['CookieTest'][0]); +?> +--EXPECT-- +string(10) "HelloWorld" diff --git a/ext/sockets/sendrecvmsg.c b/ext/sockets/sendrecvmsg.c index d9a8190736..1d9cc78e73 100644 --- a/ext/sockets/sendrecvmsg.c +++ b/ext/sockets/sendrecvmsg.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2012 The PHP Group | + | Copyright (c) 1997-2014 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 | diff --git a/ext/sockets/windows_common.h b/ext/sockets/windows_common.h index 3a9cb59129..9cc01ae129 100644 --- a/ext/sockets/windows_common.h +++ b/ext/sockets/windows_common.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2012 The PHP Group | + | Copyright (c) 1997-2014 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 | diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 3e97e9448d..c631c187c9 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -402,7 +402,7 @@ static zval *spl_array_read_dimension_ex(int check_inherited, zval *object, zval /* When in a write context, * ZE has to be fooled into thinking this is in a reference set * by separating (if necessary) and returning as an is_ref=1 zval (even if refcount == 1) */ - if ((type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) && !Z_ISREF_PP(ret)) { + if ((type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) && !Z_ISREF_PP(ret) && ret != &EG(uninitialized_zval_ptr)) { if (Z_REFCOUNT_PP(ret) > 1) { zval *newval; @@ -603,7 +603,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o if (rv && zend_is_true(rv TSRMLS_CC)) { zval_ptr_dtor(&rv); - if (check_empty == 2) { + if (check_empty != 1) { return 1; } else if (intern->fptr_offset_get) { value = spl_array_read_dimension_ex(1, object, offset, BP_VAR_R TSRMLS_CC); @@ -629,6 +629,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o return 0; } break; + case IS_DOUBLE: case IS_RESOURCE: case IS_BOOL: @@ -646,28 +647,20 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o return 0; } break; + default: zend_error(E_WARNING, "Illegal offset type"); return 0; } - if (check_inherited && intern->fptr_offset_get) { + if (check_empty && check_inherited && intern->fptr_offset_get) { value = spl_array_read_dimension_ex(1, object, offset, BP_VAR_R TSRMLS_CC); } else { value = *tmp; } } - switch (check_empty) { - case 0: - return Z_TYPE_P(value) != IS_NULL; - case 2: - return 1; - case 1: - return zend_is_true(value TSRMLS_CC); - } - - return 0; + return check_empty ? zend_is_true(value TSRMLS_CC) : Z_TYPE_P(value) != IS_NULL; } /* }}} */ static int spl_array_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC) /* {{{ */ @@ -938,7 +931,14 @@ static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht TSR if (Z_TYPE_P(intern->array) == IS_OBJECT) { do { if (zend_hash_get_current_key_ex(aht, &string_key, &string_length, &num_key, 0, &intern->pos) == HASH_KEY_IS_STRING) { - if (!string_length || string_key[0]) { + /* zend_hash_get_current_key_ex() should never set + * string_length to 0 when returning HASH_KEY_IS_STRING, but we + * may as well be defensive and consider that successful. + * Beyond that, we're looking for protected keys (which will + * have a null byte at string_key[0]), but want to avoid + * skipping completely empty keys (which will also have the + * null byte, but a string_length of 1). */ + if (!string_length || string_key[0] || string_length == 1) { return SUCCESS; } } else { @@ -1742,6 +1742,7 @@ SPL_METHOD(Array, unserialize) const unsigned char *p, *s; php_unserialize_data_t var_hash; zval *pmembers, *pflags = NULL; + HashTable *aht; long flags; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { @@ -1749,7 +1750,12 @@ SPL_METHOD(Array, unserialize) } if (buf_len == 0) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Empty serialized string cannot be empty"); + return; + } + + aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); + if (aht->nApplyCount > 0) { + zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited"); return; } @@ -1805,7 +1811,7 @@ SPL_METHOD(Array, unserialize) ++p; ALLOC_INIT_ZVAL(pmembers); - if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC)) { + if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pmembers) != IS_ARRAY) { zval_ptr_dtor(&pmembers); goto outexcept; } diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index edb4c071cf..0d5cccf0c9 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -829,6 +829,7 @@ SPL_METHOD(DirectoryIterator, seek) zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_rewind, "rewind", &retval); if (retval) { zval_ptr_dtor(&retval); + retval = NULL; } } @@ -838,6 +839,7 @@ SPL_METHOD(DirectoryIterator, seek) if (retval) { valid = zend_is_true(retval TSRMLS_CC); zval_ptr_dtor(&retval); + retval = NULL; } if (!valid) { break; diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 772d780e01..c48736ec6c 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -43,12 +43,10 @@ PHPAPI zend_class_entry *spl_ce_SplStack; #define SPL_LLIST_DELREF(elem) if(!--(elem)->rc) { \ efree(elem); \ - elem = NULL; \ } #define SPL_LLIST_CHECK_DELREF(elem) if((elem) && !--(elem)->rc) { \ efree(elem); \ - elem = NULL; \ } #define SPL_LLIST_ADDREF(elem) (elem)->rc++ @@ -916,6 +914,11 @@ SPL_METHOD(SplDoublyLinkedList, offsetUnset) llist->dtor(element TSRMLS_CC); } + if (intern->traverse_pointer == element) { + SPL_LLIST_DELREF(element); + intern->traverse_pointer = NULL; + } + zval_ptr_dtor((zval **)&element->data); element->data = NULL; @@ -1192,7 +1195,6 @@ SPL_METHOD(SplDoublyLinkedList, unserialize) } if (buf_len == 0) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Serialized string cannot be empty"); return; } diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index dcd1582d60..2c5d5f626c 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -116,7 +116,7 @@ static void spl_fixedarray_resize(spl_fixedarray *array, long size TSRMLS_DC) /* array->elements = NULL; } } else if (size > array->size) { - array->elements = erealloc(array->elements, sizeof(zval *) * size); + array->elements = safe_erealloc(array->elements, size, sizeof(zval *), 0); memset(array->elements + array->size, '\0', sizeof(zval *) * (size - array->size)); } else { /* size < array->size */ long i; diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 3068ccc795..b9901f8f27 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -848,6 +848,8 @@ static union _zend_function *spl_recursive_it_get_method(zval **object_ptr, char *object_ptr = zobj; function_handler = Z_OBJ_HT_P(*object_ptr)->get_method(object_ptr, method, method_len, key TSRMLS_CC); } + } else { + *object_ptr = zobj; } } return function_handler; diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index 91830ab000..f493154b20 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -831,7 +831,6 @@ SPL_METHOD(SplObjectStorage, unserialize) } if (buf_len == 0) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Empty serialized string cannot be empty"); return; } @@ -915,7 +914,7 @@ SPL_METHOD(SplObjectStorage, unserialize) ++p; ALLOC_INIT_ZVAL(pmembers); - if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC)) { + if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pmembers) != IS_ARRAY) { zval_ptr_dtor(&pmembers); goto outexcept; } diff --git a/ext/spl/tests/ArrayObject_unserialize_empty_string.phpt b/ext/spl/tests/ArrayObject_unserialize_empty_string.phpt index 75d8a41321..4c446c82b9 100644 --- a/ext/spl/tests/ArrayObject_unserialize_empty_string.phpt +++ b/ext/spl/tests/ArrayObject_unserialize_empty_string.phpt @@ -1,5 +1,5 @@ --TEST-- -ArrayObject: test that you cannot unserialize a empty string +ArrayObject: test that you can unserialize a empty string --CREDITS-- Havard Eide <nucleuz@gmail.com> #PHPTestFest2009 Norway 2009-06-09 \o/ @@ -8,9 +8,6 @@ Havard Eide <nucleuz@gmail.com> $a = new ArrayObject(array()); $a->unserialize(""); ?> +Done --EXPECTF-- -Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Empty serialized string cannot be empty' in %s.php:%d -Stack trace: -#0 %s(%d): ArrayObject->unserialize('') -#1 {main} - thrown in %s.php on line %d +Done diff --git a/ext/spl/tests/SplObjectStorage_unserialize_bad.phpt b/ext/spl/tests/SplObjectStorage_unserialize_bad.phpt index a525317093..8f0676de3b 100644 --- a/ext/spl/tests/SplObjectStorage_unserialize_bad.phpt +++ b/ext/spl/tests/SplObjectStorage_unserialize_bad.phpt @@ -7,6 +7,7 @@ $badblobs = array( 'x:i:2;i:0;,i:1;;i:0;,i:2;;m:a:0:{}', 'x:i:3;O:8:"stdClass":0:{},O:8:"stdClass":0:{};R:2;,i:1;;O:8:"stdClass":0:{},r:2;;m:a:0:{}', 'x:i:3;O:8:"stdClass":0:{},O:8:"stdClass":0:{};r:2;,i:1;;O:8:"stdClass":0:{},r:2;;m:a:0:{}', +'x:i:1;O:8:"stdClass":0:{},N;;m:s:40:"1234567890123456789012345678901234567890"', ); foreach($badblobs as $blob) { try { @@ -17,6 +18,7 @@ try { echo $e->getMessage()."\n"; } } +echo "DONE\n"; --EXPECTF-- Error at offset 6 of 34 bytes Error at offset 46 of 89 bytes @@ -42,4 +44,5 @@ object(SplObjectStorage)#2 (1) { } } } - +Error at offset 79 of 78 bytes +DONE diff --git a/ext/spl/tests/SplObjectStorage_unserialize_invalid_parameter3.phpt b/ext/spl/tests/SplObjectStorage_unserialize_invalid_parameter3.phpt index 4c2dd75e14..617f85e63c 100644 --- a/ext/spl/tests/SplObjectStorage_unserialize_invalid_parameter3.phpt +++ b/ext/spl/tests/SplObjectStorage_unserialize_invalid_parameter3.phpt @@ -1,5 +1,5 @@ --TEST-- -Check that SplObjectStorage::unserialize throws exception when NULL passed +Check that SplObjectStorage::unserialize doesn't throws exception when NULL passed --CREDITS-- PHPNW Testfest 2009 - Simon Westcott (swestcott@gmail.com) --FILE-- @@ -14,6 +14,6 @@ try { } ?> +Done --EXPECTF-- -Empty serialized string cannot be empty - +Done diff --git a/ext/spl/tests/bug66127.phpt b/ext/spl/tests/bug66127.phpt new file mode 100644 index 0000000000..b5d1dcac4b --- /dev/null +++ b/ext/spl/tests/bug66127.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #66127 (Segmentation fault with ArrayObject unset) +--INI-- +error_reporting = E_ALL & ~E_NOTICE +--FILE-- +<?php +function crash() +{ + set_error_handler(function () {}); + $var = 1; + trigger_error('error'); + $var2 = $var; + $var3 = $var; + trigger_error('error'); +} + +$items = new ArrayObject(); + +unset($items[0]); +unset($items[0][0]); +crash(); +echo "Worked!\n"; +?> +--EXPECT-- +Worked! diff --git a/ext/spl/tests/bug66834.phpt b/ext/spl/tests/bug66834.phpt index 6d944b274a..66686c771a 100644 --- a/ext/spl/tests/bug66834.phpt +++ b/ext/spl/tests/bug66834.phpt @@ -75,14 +75,13 @@ var_dump($object->offsetexists('qux'), isset($object['qux']), empty($object['qux echo "==== class with offsetGet() and offsetSet() ====\n"; $object = new ArrayObjectGetSet; $object['foo'] = 42; -var_dump($object->offsetExists('foo'), $object->offsetExists('sbb'), isset($object['foo']), isset($object['sbb'])); +var_dump($object->offsetExists('foo'), $object->offsetExists('sbb'), isset($object['foo']), isset($object['sbb']), empty($object['sbb'])); ?> --EXPECTF-- ==== class with offsetExists() and offsetGet() ==== string(37) "Called: ArrayObjectBoth::offsetExists" string(37) "Called: ArrayObjectBoth::offsetExists" -string(34) "Called: ArrayObjectBoth::offsetGet" string(37) "Called: ArrayObjectBoth::offsetExists" string(34) "Called: ArrayObjectBoth::offsetGet" bool(true) @@ -90,15 +89,13 @@ bool(true) bool(true) string(37) "Called: ArrayObjectBoth::offsetExists" string(37) "Called: ArrayObjectBoth::offsetExists" -string(34) "Called: ArrayObjectBoth::offsetGet" string(37) "Called: ArrayObjectBoth::offsetExists" string(34) "Called: ArrayObjectBoth::offsetGet" bool(true) -bool(false) +bool(true) bool(true) string(37) "Called: ArrayObjectBoth::offsetExists" string(37) "Called: ArrayObjectBoth::offsetExists" -string(34) "Called: ArrayObjectBoth::offsetGet" string(37) "Called: ArrayObjectBoth::offsetExists" string(34) "Called: ArrayObjectBoth::offsetGet" bool(true) @@ -121,7 +118,7 @@ string(39) "Called: ArrayObjectExists::offsetExists" string(39) "Called: ArrayObjectExists::offsetExists" string(39) "Called: ArrayObjectExists::offsetExists" bool(true) -bool(false) +bool(true) bool(true) string(39) "Called: ArrayObjectExists::offsetExists" string(39) "Called: ArrayObjectExists::offsetExists" @@ -137,17 +134,14 @@ bool(false) bool(true) ==== class with offsetGet() ==== string(33) "Called: ArrayObjectGet::offsetGet" -string(33) "Called: ArrayObjectGet::offsetGet" bool(true) bool(true) bool(true) string(33) "Called: ArrayObjectGet::offsetGet" -string(33) "Called: ArrayObjectGet::offsetGet" bool(true) bool(false) bool(true) string(33) "Called: ArrayObjectGet::offsetGet" -string(33) "Called: ArrayObjectGet::offsetGet" bool(true) bool(true) bool(false) @@ -160,4 +154,5 @@ Notice: Undefined index: foo in %s on line %d bool(false) bool(true) bool(false) -bool(false) +bool(true) +bool(true) diff --git a/ext/spl/tests/bug67247.phpt b/ext/spl/tests/bug67247.phpt new file mode 100644 index 0000000000..cb71445d7b --- /dev/null +++ b/ext/spl/tests/bug67247.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #67247 (spl_fixedarray_resize integer overflow) +--FILE-- +<?php +$ar = new SplFixedArray(1); +echo "size: ".$ar->getSize()."\n"; +$ar->setSize((PHP_INT_SIZE==8)?0x2000000000000001:0x40000001); +echo "size: ".$ar->getSize()."\n"; +?> +--EXPECTF-- +size: 1 + +Fatal error: Possible integer overflow in memory allocation (%d * %d + 0) in %s on line %d diff --git a/ext/spl/tests/bug67359.phpt b/ext/spl/tests/bug67359.phpt new file mode 100644 index 0000000000..e2e61133f3 --- /dev/null +++ b/ext/spl/tests/bug67359.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #67359 (Segfault in recursiveDirectoryIterator) +--FILE-- +<?php +try +{ + $rdi = new recursiveDirectoryIterator(dirname(__FILE__), FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS); + $it = new recursiveIteratorIterator( $rdi ); + $it->seek(1); + while( $it->valid()) + { + if( $it->isFile() ) + { + $it->current(); + } + + $it->next(); + } + + $it->current(); +} +catch(Exception $e) +{ +} +echo "okey" +?> +--EXPECTF-- +okey diff --git a/ext/spl/tests/bug67360.phpt b/ext/spl/tests/bug67360.phpt new file mode 100644 index 0000000000..552c02ad74 --- /dev/null +++ b/ext/spl/tests/bug67360.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #67360 (Missing element after ArrayObject::getIterator) +--FILE-- +<?php + +$array = array('' => 1, 1 => 2, 3 => 4); +$ArrayObject = new ArrayObject($array); +var_dump($ArrayObject); +$Iterator = $ArrayObject->getIterator(); +var_dump(count($Iterator) === count($array)); +var_dump(iterator_to_array($Iterator)); + +?> +--EXPECTF-- +object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + array(3) { + [""]=> + int(1) + [1]=> + int(2) + [3]=> + int(4) + } +} +bool(true) +array(3) { + [""]=> + int(1) + [1]=> + int(2) + [3]=> + int(4) +} diff --git a/ext/spl/tests/bug67538.phpt b/ext/spl/tests/bug67538.phpt new file mode 100644 index 0000000000..b6f3848c36 --- /dev/null +++ b/ext/spl/tests/bug67538.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #67538 (SPL Iterators use-after-free) +--FILE-- +<?php +$list = new SplDoublyLinkedList(); +$list->push('a'); +$list->push('b'); + +$list->rewind(); +$list->offsetUnset(0); +$list->push('b'); +$list->offsetUnset(0); +$list->next(); +echo "okey"; +?> +--EXPECTF-- +okey diff --git a/ext/spl/tests/bug67539.phpt b/ext/spl/tests/bug67539.phpt new file mode 100644 index 0000000000..8bab2a8c21 --- /dev/null +++ b/ext/spl/tests/bug67539.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #67539 (ArrayIterator use-after-free due to object change during sorting) +--FILE-- +<?php + +$it = new ArrayIterator(array_fill(0,2,'X'), 1 ); + +function badsort($a, $b) { + $GLOBALS['it']->unserialize($GLOBALS['it']->serialize()); + return TRUE; +} + +$it->uksort('badsort'); +--EXPECTF-- +Warning: Modification of ArrayObject during sorting is prohibited in %sbug67539.php on line %d diff --git a/ext/spl/tests/iterator_035.phpt b/ext/spl/tests/iterator_035.phpt index 9ce098b69d..fc0271e381 100644 --- a/ext/spl/tests/iterator_035.phpt +++ b/ext/spl/tests/iterator_035.phpt @@ -12,4 +12,6 @@ $a[] = &$tmp; echo "Done\n"; ?> --EXPECTF-- +Notice: Indirect modification of overloaded element of ArrayIterator has no effect in %s on line %d + Fatal error: Cannot assign by reference to overloaded object in %s on line %d diff --git a/ext/spl/tests/unserialize.phpt b/ext/spl/tests/unserialize.phpt new file mode 100644 index 0000000000..3232b79678 --- /dev/null +++ b/ext/spl/tests/unserialize.phpt @@ -0,0 +1,43 @@ +--TEST-- +SPL: unserialize with no data (for PHPUnit) +--FILE-- +<?php + +$types = array('SplDoublyLinkedList', 'SplObjectStorage', 'ArrayObject'); + +foreach ($types as $type) { + // serialize an empty new object + $exp = serialize(new $type()); + // hack to instanciate an object without constructor + $str = sprintf('C:%d:"%s":0:{}', strlen($type), $type); + $obj = unserialize($str); + var_dump($obj); + // serialize result + $out = serialize($obj); + // both should match + var_dump($exp === $out); +} +?> +===DONE=== +--EXPECTF-- +object(SplDoublyLinkedList)#%d (2) { + ["flags":"SplDoublyLinkedList":private]=> + int(0) + ["dllist":"SplDoublyLinkedList":private]=> + array(0) { + } +} +bool(true) +object(SplObjectStorage)#%d (1) { + ["storage":"SplObjectStorage":private]=> + array(0) { + } +} +bool(true) +object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + array(0) { + } +} +bool(true) +===DONE=== diff --git a/ext/standard/array.c b/ext/standard/array.c index 450e6995c2..54e8951f23 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -342,8 +342,7 @@ PHP_FUNCTION(count) RETVAL_LONG(Z_LVAL_P(retval)); zval_ptr_dtor(&retval); } - zval_dtor(mode_zv); - efree(mode_zv); + zval_ptr_dtor(&mode_zv); return; } #endif diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index de3719e1e9..dd4e59ec7c 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2636,7 +2636,6 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_unserialize, 0, 0, 1) ZEND_ARG_INFO(0, variable_representation) - ZEND_ARG_INFO(1, consumed) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_memory_get_usage, 0, 0, 0) @@ -4029,92 +4028,91 @@ PHP_FUNCTION(putenv) { char *setting; int setting_len; + char *p, **env; + putenv_entry pe; +#ifdef PHP_WIN32 + char *value = NULL; + int equals = 0; + int error_code; +#endif if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &setting, &setting_len) == FAILURE) { return; } + + if(setting_len == 0 || setting[0] == '=') { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter syntax"); + RETURN_FALSE; + } - if (setting_len) { - char *p, **env; - putenv_entry pe; + pe.putenv_string = estrndup(setting, setting_len); + pe.key = estrndup(setting, setting_len); + if ((p = strchr(pe.key, '='))) { /* nullify the '=' if there is one */ + *p = '\0'; #ifdef PHP_WIN32 - char *value = NULL; - int equals = 0; - int error_code; + equals = 1; #endif + } - pe.putenv_string = estrndup(setting, setting_len); - pe.key = estrndup(setting, setting_len); - if ((p = strchr(pe.key, '='))) { /* nullify the '=' if there is one */ - *p = '\0'; -#ifdef PHP_WIN32 - equals = 1; -#endif - } - - pe.key_len = strlen(pe.key); + pe.key_len = strlen(pe.key); #ifdef PHP_WIN32 - if (equals) { - if (pe.key_len < setting_len - 1) { - value = p + 1; - } else { - /* empty string*/ - value = p; - } + if (equals) { + if (pe.key_len < setting_len - 1) { + value = p + 1; + } else { + /* empty string*/ + value = p; } + } #endif - zend_hash_del(&BG(putenv_ht), pe.key, pe.key_len+1); + zend_hash_del(&BG(putenv_ht), pe.key, pe.key_len+1); - /* find previous value */ - pe.previous_value = NULL; - for (env = environ; env != NULL && *env != NULL; env++) { - if (!strncmp(*env, pe.key, pe.key_len) && (*env)[pe.key_len] == '=') { /* found it */ + /* find previous value */ + pe.previous_value = NULL; + for (env = environ; env != NULL && *env != NULL; env++) { + if (!strncmp(*env, pe.key, pe.key_len) && (*env)[pe.key_len] == '=') { /* found it */ #if defined(PHP_WIN32) - /* must copy previous value because MSVCRT's putenv can free the string without notice */ - pe.previous_value = estrdup(*env); + /* must copy previous value because MSVCRT's putenv can free the string without notice */ + pe.previous_value = estrdup(*env); #else - pe.previous_value = *env; + pe.previous_value = *env; #endif - break; - } + break; } + } #if HAVE_UNSETENV - if (!p) { /* no '=' means we want to unset it */ - unsetenv(pe.putenv_string); - } - if (!p || putenv(pe.putenv_string) == 0) { /* success */ + if (!p) { /* no '=' means we want to unset it */ + unsetenv(pe.putenv_string); + } + if (!p || putenv(pe.putenv_string) == 0) { /* success */ #else # ifndef PHP_WIN32 - if (putenv(pe.putenv_string) == 0) { /* success */ + if (putenv(pe.putenv_string) == 0) { /* success */ # else - error_code = SetEnvironmentVariable(pe.key, value); + error_code = SetEnvironmentVariable(pe.key, value); # if _MSC_VER < 1500 - /* Yet another VC6 bug, unset may return env not found */ - if (error_code != 0 || - (error_code == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND)) { + /* Yet another VC6 bug, unset may return env not found */ + if (error_code != 0 || + (error_code == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND)) { # else - if (error_code != 0) { /* success */ + if (error_code != 0) { /* success */ # endif # endif #endif - zend_hash_add(&BG(putenv_ht), pe.key, pe.key_len + 1, (void **) &pe, sizeof(putenv_entry), NULL); + zend_hash_add(&BG(putenv_ht), pe.key, pe.key_len + 1, (void **) &pe, sizeof(putenv_entry), NULL); #ifdef HAVE_TZSET - if (!strncmp(pe.key, "TZ", pe.key_len)) { - tzset(); - } -#endif - RETURN_TRUE; - } else { - efree(pe.putenv_string); - efree(pe.key); - RETURN_FALSE; + if (!strncmp(pe.key, "TZ", pe.key_len)) { + tzset(); } +#endif + RETURN_TRUE; + } else { + efree(pe.putenv_string); + efree(pe.key); + RETURN_FALSE; } - - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter syntax"); - RETURN_FALSE; } /* }}} */ #endif diff --git a/ext/standard/credits.c b/ext/standard/credits.c index 006c2d4c1a..3cb6eef724 100644 --- a/ext/standard/credits.c +++ b/ext/standard/credits.c @@ -61,10 +61,10 @@ PHPAPI void php_print_credits(int flag TSRMLS_DC) /* {{{ */ php_info_print_table_start(); php_info_print_table_colspan_header(2, "PHP Authors"); php_info_print_table_header(2, "Contribution", "Authors"); - CREDIT_LINE("Zend Scripting Language Engine", "Andi Gutmans, Zeev Suraski, Stanislav Malyshev, Marcus Boerger, Dmitry Stogov"); + CREDIT_LINE("Zend Scripting Language Engine", "Andi Gutmans, Zeev Suraski, Stanislav Malyshev, Marcus Boerger, Dmitry Stogov, Xinchen Hui, Nikita Popov"); CREDIT_LINE("Extension Module API", "Andi Gutmans, Zeev Suraski, Andrei Zmievski"); CREDIT_LINE("UNIX Build and Modularization", "Stig Bakken, Sascha Schumann, Jani Taskinen"); - CREDIT_LINE("Windows Port", "Shane Caraveo, Zeev Suraski, Wez Furlong, Pierre-Alain Joye"); + CREDIT_LINE("Windows Port", "Shane Caraveo, Zeev Suraski, Wez Furlong, Pierre-Alain Joye, Anatol Belski"); CREDIT_LINE("Server API (SAPI) Abstraction Layer", "Andi Gutmans, Shane Caraveo, Zeev Suraski"); CREDIT_LINE("Streams Abstraction Layer", "Wez Furlong, Sara Golemon"); CREDIT_LINE("PHP Data Objects Layer", "Wez Furlong, Marcus Boerger, Sterling Hughes, George Schlossnagle, Ilia Alshanetsky"); @@ -95,7 +95,7 @@ PHPAPI void php_print_credits(int flag TSRMLS_DC) /* {{{ */ if (flag & PHP_CREDITS_DOCS) { php_info_print_table_start(); php_info_print_table_colspan_header(2, "PHP Documentation"); - CREDIT_LINE("Authors", "Mehdi Achour, Friedhelm Betz, Antony Dovgal, Nuno Lopes, Hannes Magnusson, Georg Richter, Damien Seguy, Jakub Vrana"); + CREDIT_LINE("Authors", "Mehdi Achour, Friedhelm Betz, Antony Dovgal, Nuno Lopes, Hannes Magnusson, Georg Richter, Damien Seguy, Jakub Vrana, Adam Harvey, Peter Cowburn"); CREDIT_LINE("Editor", "Philip Olson"); CREDIT_LINE("User Note Maintainers", "Daniel P. Brown, Thiago Henrique Pojda"); CREDIT_LINE("Other Contributors", "Previously active authors, editors and other contributors are listed in the manual."); @@ -105,7 +105,7 @@ PHPAPI void php_print_credits(int flag TSRMLS_DC) /* {{{ */ if (flag & PHP_CREDITS_QA) { php_info_print_table_start(); php_info_print_table_header(1, "PHP Quality Assurance Team"); - php_info_print_table_row(1, "Ilia Alshanetsky, Joerg Behrens, Antony Dovgal, Stefan Esser, Moriyoshi Koizumi, Magnus Maatta, Sebastian Nohn, Derick Rethans, Melvyn Sopacua, Jani Taskinen, Pierre-Alain Joye, Dmitry Stogov, Felipe Pena, David Soria Parra"); + php_info_print_table_row(1, "Ilia Alshanetsky, Joerg Behrens, Antony Dovgal, Stefan Esser, Moriyoshi Koizumi, Magnus Maatta, Sebastian Nohn, Derick Rethans, Melvyn Sopacua, Jani Taskinen, Pierre-Alain Joye, Dmitry Stogov, Felipe Pena, David Soria Parra, Stanislav Malyshev, Julien Pauli, Stephen Zarkos, Anatol Belski, Remi Collet, Ferenc Kovacs"); php_info_print_table_end(); } @@ -115,7 +115,7 @@ PHPAPI void php_print_credits(int flag TSRMLS_DC) /* {{{ */ php_info_print_table_start(); php_info_print_table_colspan_header(2, "Websites and Infrastructure team"); /* www., wiki., windows., master., and others, I guess pecl. too? */ - CREDIT_LINE("PHP Websites Team", "Rasmus Lerdorf, Hannes Magnusson, Philip Olson, Lukas Kahwe Smith, Pierre-Alain Joye, Kalle Sommer Nielsen"); + CREDIT_LINE("PHP Websites Team", "Rasmus Lerdorf, Hannes Magnusson, Philip Olson, Lukas Kahwe Smith, Pierre-Alain Joye, Kalle Sommer Nielsen, Peter Cowburn, Adam Harvey, Ferenc Kovacs, Levi Morrison"); CREDIT_LINE("Event Maintainers", "Damien Seguy, Daniel P. Brown"); /* Mirroring */ CREDIT_LINE("Network Infrastructure", "Daniel P. Brown"); diff --git a/ext/standard/dns.c b/ext/standard/dns.c index 6a894467ff..214a7dc7e9 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -517,6 +517,10 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int while (ll < dlen) { n = cp[ll]; + if ((ll + n) >= dlen) { + // Invalid chunk length, truncate + n = dlen - (ll + 1); + } memcpy(tp + ll , cp + ll + 1, n); add_next_index_stringl(entries, cp + ll + 1, n, 1); ll = ll + n + 1; diff --git a/ext/standard/file.c b/ext/standard/file.c index 74df6dc759..10ed693f01 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -527,7 +527,7 @@ PHP_FUNCTION(file_get_contents) char *contents; zend_bool use_include_path = 0; php_stream *stream; - int len; + long len; long offset = -1; long maxlen = PHP_STREAM_COPY_ALL; zval *zcontext = NULL; @@ -559,6 +559,10 @@ PHP_FUNCTION(file_get_contents) } if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) { + if (len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "content truncated from %ld to %d bytes", len, INT_MAX); + len = INT_MAX; + } RETVAL_STRINGL(contents, len, 0); } else if (len == 0) { RETVAL_EMPTY_STRING(); @@ -578,7 +582,7 @@ PHP_FUNCTION(file_put_contents) char *filename; int filename_len; zval *data; - int numbytes = 0; + long numbytes = 0; long flags = 0; zval *zcontext = NULL; php_stream_context *context = NULL; @@ -630,6 +634,10 @@ PHP_FUNCTION(file_put_contents) if (php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL, &len) != SUCCESS) { numbytes = -1; } else { + if (len > LONG_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "content truncated from %lu to %ld bytes", (unsigned long) len, LONG_MAX); + len = LONG_MAX; + } numbytes = len; } break; @@ -645,7 +653,7 @@ PHP_FUNCTION(file_put_contents) if (Z_STRLEN_P(data)) { numbytes = php_stream_write(stream, Z_STRVAL_P(data), Z_STRLEN_P(data)); if (numbytes != Z_STRLEN_P(data)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN_P(data)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %ld of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN_P(data)); numbytes = -1; } } @@ -688,7 +696,7 @@ PHP_FUNCTION(file_put_contents) if (zend_std_cast_object_tostring(data, &out, IS_STRING TSRMLS_CC) == SUCCESS) { numbytes = php_stream_write(stream, Z_STRVAL(out), Z_STRLEN(out)); if (numbytes != Z_STRLEN(out)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN(out)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %ld of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN(out)); numbytes = -1; } zval_dtor(&out); @@ -1668,7 +1676,7 @@ PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_flg, php return FAILURE; } - switch (php_stream_stat_path_ex(dest, PHP_STREAM_URL_STAT_QUIET, &dest_s, ctx)) { + switch (php_stream_stat_path_ex(dest, PHP_STREAM_URL_STAT_QUIET | PHP_STREAM_URL_STAT_NOCACHE, &dest_s, ctx)) { case -1: /* non-statable stream */ goto safe_to_copy; diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index 3cd5839313..2592b1655d 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -376,6 +376,7 @@ php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC int alignment, currarg, adjusting, argnum, width, precision; char *format, *result, padding; int always_sign; + int format_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) { return NULL; @@ -414,11 +415,12 @@ php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC convert_to_string_ex(args[format_offset]); format = Z_STRVAL_PP(args[format_offset]); + format_len = Z_STRLEN_PP(args[format_offset]); result = emalloc(size); currarg = 1; - while (inpos<Z_STRLEN_PP(args[format_offset])) { + while (inpos<format_len) { int expprec = 0, multiuse = 0; zval *tmp; @@ -473,7 +475,7 @@ php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC /* space padding, the default */ } else if (format[inpos] == '+') { always_sign = 1; - } else if (format[inpos] == '\'') { + } else if (format[inpos] == '\'' && inpos+1<format_len) { padding = format[++inpos]; } else { PRINTF_DEBUG(("sprintf: end of modifiers\n")); diff --git a/ext/standard/head.c b/ext/standard/head.c index eca032a97b..0316903bc6 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -124,7 +124,7 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t if (expires > 0) { const char *p; char tsdelta[13]; - strlcat(cookie, "; expires=", len + 100); + strlcat(cookie, COOKIE_EXPIRES, len + 100); dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC); /* check to make sure that the year does not exceed 4 digits in length */ p = zend_memrchr(dt, '-', strlen(dt)); @@ -139,7 +139,7 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t efree(dt); snprintf(tsdelta, sizeof(tsdelta), "%li", (long) difftime(expires, time(NULL))); - strlcat(cookie, "; Max-Age=", len + 100); + strlcat(cookie, COOKIE_MAX_AGE, len + 100); strlcat(cookie, tsdelta, len + 100); } } @@ -149,18 +149,18 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t } if (path && path_len > 0) { - strlcat(cookie, "; path=", len + 100); + strlcat(cookie, COOKIE_PATH, len + 100); strlcat(cookie, path, len + 100); } if (domain && domain_len > 0) { - strlcat(cookie, "; domain=", len + 100); + strlcat(cookie, COOKIE_DOMAIN, len + 100); strlcat(cookie, domain, len + 100); } if (secure) { - strlcat(cookie, "; secure", len + 100); + strlcat(cookie, COOKIE_SECURE, len + 100); } if (httponly) { - strlcat(cookie, "; httponly", len + 100); + strlcat(cookie, COOKIE_HTTPONLY, len + 100); } ctr.line = cookie; diff --git a/ext/standard/head.h b/ext/standard/head.h index efca9b8637..59b1518676 100644 --- a/ext/standard/head.h +++ b/ext/standard/head.h @@ -21,6 +21,13 @@ #ifndef HEAD_H #define HEAD_H +#define COOKIE_EXPIRES "; expires=" +#define COOKIE_MAX_AGE "; Max-Age=" +#define COOKIE_DOMAIN "; domain=" +#define COOKIE_PATH "; path=" +#define COOKIE_SECURE "; secure" +#define COOKIE_HTTPONLY "; HttpOnly" + extern PHP_RINIT_FUNCTION(head); PHP_FUNCTION(header); PHP_FUNCTION(header_remove); diff --git a/ext/standard/html.c b/ext/standard/html.c index 5bbe39ccbb..fd210c8086 100644 --- a/ext/standard/html.c +++ b/ext/standard/html.c @@ -901,7 +901,7 @@ static inline size_t write_octet_sequence(unsigned char *buf, enum entity_charse #if 0 return php_mb2_int_to_char(buf, code); #else -#ifdef ZEND_DEBUG +#if ZEND_DEBUG assert(code <= 0xFFU); #endif *buf = code; @@ -912,7 +912,7 @@ static inline size_t write_octet_sequence(unsigned char *buf, enum entity_charse #if 0 /* idem */ return php_mb2_int_to_char(buf, code); #else -#ifdef ZEND_DEBUG +#if ZEND_DEBUG assert(code <= 0xFFU); #endif *buf = code; diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 3ef722bde0..ce4c2ba0ea 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -752,10 +752,11 @@ finish: SEPARATE_ZVAL(tmpzval); convert_to_long_ex(tmpzval); follow_location = Z_LVAL_PP(tmpzval); - } else if (!(response_code >= 300 && response_code < 304 || 307 == response_code)) { + } else if (!(response_code >= 300 && response_code < 304 || 307 == response_code || 308 == response_code)) { /* we shouldn't redirect automatically if follow_location isn't set and response_code not in (300, 301, 302, 303 and 307) - see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1 */ + see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1 + RFC 7238 defines 308: http://tools.ietf.org/html/rfc7238 */ follow_location = 0; } strlcpy(location, http_header_line + 10, sizeof(location)); diff --git a/ext/standard/info.c b/ext/standard/info.c index 03ced35fb3..0626a7067b 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -866,16 +866,16 @@ PHPAPI void php_print_info(int flag TSRMLS_DC) php_info_print_table_start(); php_info_print_table_header(2, "Variable", "Value"); - if (zend_hash_find(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF"), (void **) &data) != FAILURE) { + if (zend_hash_find(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF"), (void **) &data) != FAILURE && Z_TYPE_PP(data) == IS_STRING) { php_info_print_table_row(2, "PHP_SELF", Z_STRVAL_PP(data)); } - if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_TYPE", sizeof("PHP_AUTH_TYPE"), (void **) &data) != FAILURE) { + if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_TYPE", sizeof("PHP_AUTH_TYPE"), (void **) &data) != FAILURE && Z_TYPE_PP(data) == IS_STRING) { php_info_print_table_row(2, "PHP_AUTH_TYPE", Z_STRVAL_PP(data)); } - if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_USER", sizeof("PHP_AUTH_USER"), (void **) &data) != FAILURE) { + if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_USER", sizeof("PHP_AUTH_USER"), (void **) &data) != FAILURE && Z_TYPE_PP(data) == IS_STRING) { php_info_print_table_row(2, "PHP_AUTH_USER", Z_STRVAL_PP(data)); } - if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_PW", sizeof("PHP_AUTH_PW"), (void **) &data) != FAILURE) { + if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_PW", sizeof("PHP_AUTH_PW"), (void **) &data) != FAILURE && Z_TYPE_PP(data) == IS_STRING) { php_info_print_table_row(2, "PHP_AUTH_PW", Z_STRVAL_PP(data)); } php_print_gpcse_array(ZEND_STRL("_REQUEST") TSRMLS_CC); diff --git a/ext/standard/iptc.c b/ext/standard/iptc.c index 3257339106..ad4fa65029 100644 --- a/ext/standard/iptc.c +++ b/ext/standard/iptc.c @@ -329,6 +329,9 @@ PHP_FUNCTION(iptcparse) recnum = buffer[ inx++ ]; if (buffer[ inx ] & (unsigned char) 0x80) { /* long tag */ + if((inx+6) >= str_len) { + break; + } len = (((long) buffer[ inx + 2 ]) << 24) + (((long) buffer[ inx + 3 ]) << 16) + (((long) buffer[ inx + 4 ]) << 8) + (((long) buffer[ inx + 5 ])); inx += 6; diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 3deb330a8f..9628c0d69d 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -64,7 +64,7 @@ php_stream_ops php_stream_output_ops = { }; typedef struct php_stream_input { /* {{{ */ - php_stream **body_ptr; + php_stream *body; off_t position; } php_stream_input_t; /* }}} */ @@ -85,13 +85,13 @@ static size_t php_stream_input_read(php_stream *stream, char *buf, size_t count int read_bytes = sapi_read_post_block(buf, count TSRMLS_CC); if (read_bytes > 0) { - php_stream_seek(*input->body_ptr, 0, SEEK_END); - php_stream_write(*input->body_ptr, buf, read_bytes); + php_stream_seek(input->body, 0, SEEK_END); + php_stream_write(input->body, buf, read_bytes); } } - php_stream_seek(*input->body_ptr, input->position, SEEK_SET); - read = php_stream_read(*input->body_ptr, buf, count); + php_stream_seek(input->body, input->position, SEEK_SET); + read = php_stream_read(input->body, buf, count); if (!read || read == (size_t) -1) { stream->eof = 1; @@ -122,9 +122,9 @@ static int php_stream_input_seek(php_stream *stream, off_t offset, int whence, o { php_stream_input_t *input = stream->abstract; - if (*input->body_ptr) { - int sought = php_stream_seek(*input->body_ptr, offset, whence); - *newoffset = (*input->body_ptr)->position; + if (input->body) { + int sought = php_stream_seek(input->body, offset, whence); + *newoffset = (input->body)->position; return sought; } @@ -228,10 +228,11 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa } input = ecalloc(1, sizeof(*input)); - if (*(input->body_ptr = &SG(request_info).request_body)) { - php_stream_rewind(*input->body_ptr); + if ((input->body = SG(request_info).request_body)) { + php_stream_rewind(input->body); } else { - *input->body_ptr = php_stream_temp_create(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE); + input->body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir)); + SG(request_info).request_body = input->body; } return php_stream_alloc(&php_stream_input_ops, input, 0, "rb"); diff --git a/ext/standard/php_rand.h b/ext/standard/php_rand.h index 2928d98c5e..0e8abb3613 100644 --- a/ext/standard/php_rand.h +++ b/ext/standard/php_rand.h @@ -27,6 +27,7 @@ #include <stdlib.h> #include "basic_functions.h" +#include "php_lcg.h" /* System Rand functions */ #ifndef RAND_MAX diff --git a/ext/standard/rand.c b/ext/standard/rand.c index b0af30aa9d..702fec2311 100644 --- a/ext/standard/rand.c +++ b/ext/standard/rand.c @@ -30,7 +30,6 @@ #include "php.h" #include "php_math.h" #include "php_rand.h" -#include "php_lcg.h" #include "basic_functions.h" diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 8d42a51af6..8df4be7fac 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -40,6 +40,8 @@ typedef unsigned long long php_timeout_ull; typedef unsigned __int64 php_timeout_ull; #endif +#define GET_CTX_OPT(stream, wrapper, name, val) (stream->context && SUCCESS == php_stream_context_get_option(stream->context, wrapper, name, &val)) + static php_stream_context *decode_context_param(zval *contextresource TSRMLS_DC); /* Streams based network functions */ @@ -407,7 +409,7 @@ PHP_FUNCTION(stream_get_contents) zval *zsrc; long maxlen = PHP_STREAM_COPY_ALL, desiredpos = -1L; - int len; + long len; char *contents = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ll", &zsrc, &maxlen, &desiredpos) == FAILURE) { @@ -439,6 +441,10 @@ PHP_FUNCTION(stream_get_contents) len = php_stream_copy_to_mem(stream, &contents, maxlen, 0); if (contents) { + if (len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "content truncated from %ld to %d bytes", len, INT_MAX); + len = INT_MAX; + } RETVAL_STRINGL(contents, len, 0); } else { RETVAL_EMPTY_STRING(); @@ -1491,16 +1497,27 @@ PHP_FUNCTION(stream_socket_enable_crypto) long cryptokind = 0; zval *zstream, *zsessstream = NULL; php_stream *stream, *sessstream = NULL; - zend_bool enable; + zend_bool enable, cryptokindnull; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb|lr", &zstream, &enable, &cryptokind, &zsessstream) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb|l!r", &zstream, &enable, &cryptokind, &cryptokindnull, &zsessstream) == FAILURE) { RETURN_FALSE; } php_stream_from_zval(stream, &zstream); - if (ZEND_NUM_ARGS() >= 3) { + if (enable) { + if (ZEND_NUM_ARGS() < 3 || cryptokindnull) { + zval **val; + + if (!GET_CTX_OPT(stream, "ssl", "crypto_method", val)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "When enabling encryption you must specify the crypto type"); + RETURN_FALSE; + } + + cryptokind = Z_LVAL_PP(val); + } + if (zsessstream) { php_stream_from_zval(sessstream, &zsessstream); } @@ -1508,9 +1525,6 @@ PHP_FUNCTION(stream_socket_enable_crypto) if (php_stream_xport_crypto_setup(stream, cryptokind, sessstream TSRMLS_CC) < 0) { RETURN_FALSE; } - } else if (enable) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "When enabling encryption you must specify the crypto type"); - RETURN_FALSE; } ret = php_stream_xport_crypto_enable(stream, enable TSRMLS_CC); diff --git a/ext/standard/string.c b/ext/standard/string.c index 9139906653..9aa7c637f9 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -3101,6 +3101,10 @@ static void php_strtr_array(zval *return_value, char *str, int slen, HashTable * int patterns_len; zend_llist *allocs; + if (zend_hash_num_elements(pats) == 0) { + RETURN_STRINGL(str, slen, 1); + } + S(&text) = str; L(&text) = slen; diff --git a/ext/standard/tests/file/bug65701.phpt b/ext/standard/tests/file/bug65701.phpt new file mode 100644 index 0000000000..2b1b5d491d --- /dev/null +++ b/ext/standard/tests/file/bug65701.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test for bug #65701: copy() doesn't work when destination filename is created by tempnam() +--CREDITS-- +Boro Sitnikovski <buritomath@yahoo.com> +--FILE-- +<?php +$file_path = dirname(__FILE__) . "/bug65701/"; + +mkdir($file_path); + +$src = $file_path . '/srcbug65701_file.txt'; +$dst = tempnam($file_path, 'dstbug65701_file.txt'); + +file_put_contents($src, "Hello World"); + +copy($src, $dst); +var_dump(filesize($dst)); +?> +--CLEAN-- +<?php +$file_path = dirname(__FILE__) . "/bug65701/"; +foreach (scandir($file_path) as $file) { + if (strpos($file, "bug65701") !== false) { + unlink($file_path . $file); + } +} +rmdir($file_path); +?> +--EXPECT-- +int(11) diff --git a/ext/standard/tests/general_functions/bug67498.phpt b/ext/standard/tests/general_functions/bug67498.phpt new file mode 100644 index 0000000000..5b5951b0f8 --- /dev/null +++ b/ext/standard/tests/general_functions/bug67498.phpt @@ -0,0 +1,15 @@ +--TEST-- +phpinfo() Type Confusion Information Leak Vulnerability +--FILE-- +<?php +$PHP_SELF = 1; +phpinfo(INFO_VARIABLES); + +?> +==DONE== +--EXPECTF-- +phpinfo() + +PHP Variables +%A +==DONE== diff --git a/ext/standard/tests/general_functions/header_redirection_001.phpt b/ext/standard/tests/general_functions/header_redirection_001.phpt new file mode 100644 index 0000000000..ecf57ec54a --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_001.phpt @@ -0,0 +1,11 @@ +--TEST-- +Location: headers change the status code +--CGI-- +--FILE-- +<?php +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 302 Moved Temporarily +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_002.phpt b/ext/standard/tests/general_functions/header_redirection_002.phpt new file mode 100644 index 0000000000..2bf6dec510 --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_002.phpt @@ -0,0 +1,12 @@ +--TEST-- +Location: headers override non-201 and 3xx response codes +--CGI-- +--FILE-- +<?php +header("HTTP/1.1 418 I'm a Teapot"); +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 302 Moved Temporarily +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_003.phpt b/ext/standard/tests/general_functions/header_redirection_003.phpt new file mode 100644 index 0000000000..678e3143ac --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_003.phpt @@ -0,0 +1,11 @@ +--TEST-- +Location: headers respect the header() response code parameter +--CGI-- +--FILE-- +<?php +header('Location: http://example.com/', true, 404); +?> +--EXPECTHEADERS-- +Status: 404 Not Found +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_004.phpt b/ext/standard/tests/general_functions/header_redirection_004.phpt new file mode 100644 index 0000000000..678e3143ac --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_004.phpt @@ -0,0 +1,11 @@ +--TEST-- +Location: headers respect the header() response code parameter +--CGI-- +--FILE-- +<?php +header('Location: http://example.com/', true, 404); +?> +--EXPECTHEADERS-- +Status: 404 Not Found +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_005.phpt b/ext/standard/tests/general_functions/header_redirection_005.phpt new file mode 100644 index 0000000000..fc3e0f7af8 --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_005.phpt @@ -0,0 +1,12 @@ +--TEST-- +Location: headers do not override the 201 response code +--CGI-- +--FILE-- +<?php +header('HTTP/1.1 201 Created'); +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 201 Created +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_006.phpt b/ext/standard/tests/general_functions/header_redirection_006.phpt new file mode 100644 index 0000000000..5fb52096ce --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_006.phpt @@ -0,0 +1,12 @@ +--TEST-- +Location: headers do not override the 300 Multiple Choices response code +--CGI-- +--FILE-- +<?php +header('HTTP/1.1 300 Multiple Choices'); +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 300 Multiple Choices +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_007.phpt b/ext/standard/tests/general_functions/header_redirection_007.phpt new file mode 100644 index 0000000000..6769b080fb --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_007.phpt @@ -0,0 +1,12 @@ +--TEST-- +Location: headers do not override the 301 Moved Permanently response code +--CGI-- +--FILE-- +<?php +header('HTTP/1.1 301 Moved Permanently'); +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 301 Moved Permanently +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_008.phpt b/ext/standard/tests/general_functions/header_redirection_008.phpt new file mode 100644 index 0000000000..50993707c1 --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_008.phpt @@ -0,0 +1,12 @@ +--TEST-- +Location: headers do not override the 302 Found response code +--CGI-- +--FILE-- +<?php +header('HTTP/1.1 302 Found'); +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 302 Found +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_009.phpt b/ext/standard/tests/general_functions/header_redirection_009.phpt new file mode 100644 index 0000000000..f8d27f9bfd --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_009.phpt @@ -0,0 +1,12 @@ +--TEST-- +Location: headers do not override the 303 See Other response code +--CGI-- +--FILE-- +<?php +header('HTTP/1.1 303 See Other'); +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 303 See Other +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_010.phpt b/ext/standard/tests/general_functions/header_redirection_010.phpt new file mode 100644 index 0000000000..316112dde7 --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_010.phpt @@ -0,0 +1,12 @@ +--TEST-- +Location: headers do not override the 304 Not Modified response code +--CGI-- +--FILE-- +<?php +header('HTTP/1.1 304 Not Modified'); +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 304 Not Modified +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_011.phpt b/ext/standard/tests/general_functions/header_redirection_011.phpt new file mode 100644 index 0000000000..bfd8789639 --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_011.phpt @@ -0,0 +1,12 @@ +--TEST-- +Location: headers do not override the 305 Use Proxy response code +--CGI-- +--FILE-- +<?php +header('HTTP/1.1 305 Use Proxy'); +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 305 Use Proxy +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_012.phpt b/ext/standard/tests/general_functions/header_redirection_012.phpt new file mode 100644 index 0000000000..657028b09c --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_012.phpt @@ -0,0 +1,12 @@ +--TEST-- +Location: headers do not override the 307 Temporary Redirect response code +--CGI-- +--FILE-- +<?php +header('HTTP/1.1 307 Temporary Redirect'); +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 307 Temporary Redirect +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_013.phpt b/ext/standard/tests/general_functions/header_redirection_013.phpt new file mode 100644 index 0000000000..4dce0d00fa --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_013.phpt @@ -0,0 +1,12 @@ +--TEST-- +Location: headers do not override the 308 Permanent Redirect response code +--CGI-- +--FILE-- +<?php +header('HTTP/1.1 308 Permanent Redirect'); +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 308 Permanent Redirect +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/header_redirection_014.phpt b/ext/standard/tests/general_functions/header_redirection_014.phpt new file mode 100644 index 0000000000..a5fb6e8fec --- /dev/null +++ b/ext/standard/tests/general_functions/header_redirection_014.phpt @@ -0,0 +1,12 @@ +--TEST-- +Location: headers do not override the 399 Choose Your Own Adventure response code +--CGI-- +--FILE-- +<?php +header('HTTP/1.1 399 Choose Your Own Adventure'); +header('Location: http://example.com/'); +?> +--EXPECTHEADERS-- +Status: 399 Choose Your Own Adventure +Location: http://example.com/ +--EXPECT-- diff --git a/ext/standard/tests/general_functions/putenv.phpt b/ext/standard/tests/general_functions/putenv.phpt index afe1badce4..254207320b 100644 --- a/ext/standard/tests/general_functions/putenv.phpt +++ b/ext/standard/tests/general_functions/putenv.phpt @@ -15,6 +15,9 @@ var_dump(getenv($var_name)); var_dump(putenv($var_name)); var_dump(getenv($var_name)); +var_dump(putenv("=123")); +var_dump(putenv("")); + echo "Done\n"; ?> --EXPECTF-- @@ -25,4 +28,10 @@ bool(true) string(0) "" bool(true) bool(false) + +Warning: putenv(): Invalid parameter syntax in %s on line %d +bool(false) + +Warning: putenv(): Invalid parameter syntax in %s on line %d +bool(false) Done diff --git a/ext/standard/tests/http/bug67430.phpt b/ext/standard/tests/http/bug67430.phpt new file mode 100644 index 0000000000..d4474fdf5d --- /dev/null +++ b/ext/standard/tests/http/bug67430.phpt @@ -0,0 +1,49 @@ +--TEST-- +Bug #67430 (http:// wrapper doesn't follow 308 redirects) +--INI-- +allow_url_fopen=1 +--SKIPIF-- +<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?> +--FILE-- +<?php +require 'server.inc'; + +function do_test($follow) { + $options = [ + 'http' => [ + 'method' => 'POST', + 'follow_location' => $follow, + ], + ]; + + $ctx = stream_context_create($options); + + $responses = [ + "data://text/plain,HTTP/1.1 308\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(true); +do_test(false); + +?> +Done +--EXPECT-- +POST / HTTP/1.0 +Host: 127.0.0.1:12342 + +GET /foo HTTP/1.0 +Host: 127.0.0.1:12342 + +POST / HTTP/1.0 +Host: 127.0.0.1:12342 + +Done diff --git a/ext/standard/tests/image/bug67250.phpt b/ext/standard/tests/image/bug67250.phpt new file mode 100644 index 0000000000..607de9f3b6 --- /dev/null +++ b/ext/standard/tests/image/bug67250.phpt @@ -0,0 +1,8 @@ +--TEST-- +Bug #67250 (iptcparse out-of-bounds read) +--FILE-- +<?php +var_dump(iptcparse("\x1C\x02_\x80___")); +?> +--EXPECT-- +bool(false) diff --git a/ext/standard/tests/network/setcookie.phpt b/ext/standard/tests/network/setcookie.phpt index bf04ec78de..3b8e551834 100644 --- a/ext/standard/tests/network/setcookie.phpt +++ b/ext/standard/tests/network/setcookie.phpt @@ -29,13 +29,13 @@ $expected = array( 'Set-Cookie: name=value; path=/path/', 'Set-Cookie: name=value; domain=domain.tld', 'Set-Cookie: name=value; secure', - 'Set-Cookie: name=value; httponly' + 'Set-Cookie: name=value; HttpOnly' ); $headers = headers_list(); if (($i = count($expected)) > count($headers)) { - echo "Less headers are being sent than expected - aborting"; + echo "Fewer headers are being sent than expected - aborting"; return; } @@ -67,4 +67,4 @@ echo ($i === 0) --EXPECTHEADERS-- --EXPECT-- -OK
\ No newline at end of file +OK diff --git a/ext/standard/tests/serialize/serialization_error_001.phpt b/ext/standard/tests/serialize/serialization_error_001.phpt index c6c17512f3..da6f50cc02 100644 --- a/ext/standard/tests/serialize/serialization_error_001.phpt +++ b/ext/standard/tests/serialize/serialization_error_001.phpt @@ -21,7 +21,7 @@ var_dump( unserialize() ); //Test serialize with one more than the expected number of arguments var_dump( serialize(1,2) ); -var_dump( unserialize(1,$x,2) ); +var_dump( unserialize(1,2) ); echo "Done"; ?> @@ -31,12 +31,12 @@ echo "Done"; Warning: serialize() expects exactly 1 parameter, 0 given in %s on line 16 NULL -Warning: unserialize() expects at least 1 parameter, 0 given in %s on line 17 +Warning: unserialize() expects exactly 1 parameter, 0 given in %s on line 17 bool(false) Warning: serialize() expects exactly 1 parameter, 2 given in %s on line 20 NULL -Warning: unserialize() expects at most 2 parameters, 3 given in %s on line 21 +Warning: unserialize() expects exactly 1 parameter, 2 given in %s on line 21 bool(false) Done diff --git a/ext/standard/tests/serialize/unserialize_consumed.phpt b/ext/standard/tests/serialize/unserialize_consumed.phpt deleted file mode 100644 index 6cc11e273f..0000000000 --- a/ext/standard/tests/serialize/unserialize_consumed.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -Unserialization of partial strings ---FILE-- -<?php -$data = [123,4.56,true]; -$ser = serialize($data); -$serlen = strlen($ser); - -$unser = unserialize($ser, $consumed); -echo "Consume full string: "; -var_dump($serlen == $consumed); -echo "Return original data: "; -var_dump($unser === $data); - -$ser .= "junk\x01data"; -$unser = unserialize($ser, $consumed); -echo "Consume full string(junk): "; -var_dump($serlen == $consumed); -echo "Return original data(junk): "; -var_dump($unser === $data); - ---EXPECT-- -Consume full string: bool(true) -Return original data: bool(true) -Consume full string(junk): bool(true) -Return original data(junk): bool(true) - diff --git a/ext/standard/tests/strings/bug67151.phpt b/ext/standard/tests/strings/bug67151.phpt new file mode 100644 index 0000000000..1d0c02a52d --- /dev/null +++ b/ext/standard/tests/strings/bug67151.phpt @@ -0,0 +1,8 @@ +--TEST-- +Buf #67151: strtr with empty array crashes +--FILE-- +<?php +var_dump(strtr("foo", [])); +?> +--EXPECT-- +string(3) "foo" diff --git a/ext/standard/tests/strings/bug67249.phpt b/ext/standard/tests/strings/bug67249.phpt new file mode 100644 index 0000000000..6ea75289e6 --- /dev/null +++ b/ext/standard/tests/strings/bug67249.phpt @@ -0,0 +1,8 @@ +--TEST-- +Bug #67249 (printf out-of-bounds read) +--FILE-- +<?php +var_dump(sprintf("%'", "foo")); +?> +--EXPECT-- +string(0) "" diff --git a/ext/standard/tests/strings/bug67252.phpt b/ext/standard/tests/strings/bug67252.phpt new file mode 100644 index 0000000000..80a6ebcf1c --- /dev/null +++ b/ext/standard/tests/strings/bug67252.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #67252 (convert_uudecode out-of-bounds read) +--FILE-- +<?php + +$a = "M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A"."\n"."a."; +var_dump(convert_uudecode($a)); + +?> +--EXPECTF-- + +Warning: convert_uudecode(): The given parameter is not a valid uuencoded string in %s on line %d +bool(false) diff --git a/ext/standard/tests/url/bug64604.phpt b/ext/standard/tests/url/bug64604.phpt deleted file mode 100644 index bbc3cb9d1b..0000000000 --- a/ext/standard/tests/url/bug64604.phpt +++ /dev/null @@ -1,40 +0,0 @@ ---TEST-- -Bug #64604 parse_url is inconsistent with specified port ---FILE-- -<?php -var_dump(parse_url('//localhost/path')); -var_dump(parse_url('//localhost:80/path')); -var_dump(parse_url('//localhost:/path')); -var_dump(parse_url('http://localhost:80/path')); -?> ---EXPECT-- -array(2) { - ["host"]=> - string(9) "localhost" - ["path"]=> - string(5) "/path" -} -array(3) { - ["host"]=> - string(9) "localhost" - ["port"]=> - int(80) - ["path"]=> - string(5) "/path" -} -array(2) { - ["host"]=> - string(9) "localhost" - ["path"]=> - string(5) "/path" -} -array(4) { - ["scheme"]=> - string(4) "http" - ["host"]=> - string(9) "localhost" - ["port"]=> - int(80) - ["path"]=> - string(5) "/path" -} diff --git a/ext/standard/tests/url/parse_url_basic_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt index 4c5b0944c6..a6f4f7a252 100644 --- a/ext/standard/tests/url/parse_url_basic_001.phpt +++ b/ext/standard/tests/url/parse_url_basic_001.phpt @@ -845,6 +845,13 @@ echo "Done"; string(1) "/" } +--> /rest/Users?filter={"id":"123"}: array(2) { + ["path"]=> + string(11) "/rest/Users" + ["query"]=> + string(19) "filter={"id":"123"}" +} + --> http:///blah.com: bool(false) --> http://:80: bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_002.phpt b/ext/standard/tests/url/parse_url_basic_002.phpt index ed0f08a84f..c05d1f487a 100644 --- a/ext/standard/tests/url/parse_url_basic_002.phpt +++ b/ext/standard/tests/url/parse_url_basic_002.phpt @@ -110,6 +110,7 @@ echo "Done"; --> http://[x:80]/ : string(4) "http" --> : NULL --> / : NULL +--> /rest/Users?filter={"id":"123"} : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_003.phpt b/ext/standard/tests/url/parse_url_basic_003.phpt index a2bbfa6482..88eda504d5 100644 --- a/ext/standard/tests/url/parse_url_basic_003.phpt +++ b/ext/standard/tests/url/parse_url_basic_003.phpt @@ -109,6 +109,7 @@ echo "Done"; --> http://[x:80]/ : string(6) "[x:80]" --> : NULL --> / : NULL +--> /rest/Users?filter={"id":"123"} : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_004.phpt b/ext/standard/tests/url/parse_url_basic_004.phpt index 839ebee554..e3b9abd91c 100644 --- a/ext/standard/tests/url/parse_url_basic_004.phpt +++ b/ext/standard/tests/url/parse_url_basic_004.phpt @@ -109,6 +109,7 @@ echo "Done"; --> http://[x:80]/ : NULL --> : NULL --> / : NULL +--> /rest/Users?filter={"id":"123"} : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_005.phpt b/ext/standard/tests/url/parse_url_basic_005.phpt index c113461fe7..1fc946e5b3 100644 --- a/ext/standard/tests/url/parse_url_basic_005.phpt +++ b/ext/standard/tests/url/parse_url_basic_005.phpt @@ -109,6 +109,7 @@ echo "Done"; --> http://[x:80]/ : NULL --> : NULL --> / : NULL +--> /rest/Users?filter={"id":"123"} : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_006.phpt b/ext/standard/tests/url/parse_url_basic_006.phpt index 24de1cc233..5104326198 100644 --- a/ext/standard/tests/url/parse_url_basic_006.phpt +++ b/ext/standard/tests/url/parse_url_basic_006.phpt @@ -109,6 +109,7 @@ echo "Done"; --> http://[x:80]/ : NULL --> : NULL --> / : NULL +--> /rest/Users?filter={"id":"123"} : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_007.phpt b/ext/standard/tests/url/parse_url_basic_007.phpt index d4006879f4..8e04553983 100644 --- a/ext/standard/tests/url/parse_url_basic_007.phpt +++ b/ext/standard/tests/url/parse_url_basic_007.phpt @@ -109,6 +109,7 @@ echo "Done"; --> http://[x:80]/ : string(1) "/" --> : string(0) "" --> / : string(1) "/" +--> /rest/Users?filter={"id":"123"} : string(11) "/rest/Users" --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_008.phpt b/ext/standard/tests/url/parse_url_basic_008.phpt index b283829c46..0c77221465 100644 --- a/ext/standard/tests/url/parse_url_basic_008.phpt +++ b/ext/standard/tests/url/parse_url_basic_008.phpt @@ -109,6 +109,7 @@ echo "Done"; --> http://[x:80]/ : NULL --> : NULL --> / : NULL +--> /rest/Users?filter={"id":"123"} : string(19) "filter={"id":"123"}" --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_009.phpt b/ext/standard/tests/url/parse_url_basic_009.phpt index a7d70f34da..487b271149 100644 --- a/ext/standard/tests/url/parse_url_basic_009.phpt +++ b/ext/standard/tests/url/parse_url_basic_009.phpt @@ -109,6 +109,7 @@ echo "Done"; --> http://[x:80]/ : NULL --> : NULL --> / : NULL +--> /rest/Users?filter={"id":"123"} : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/urls.inc b/ext/standard/tests/url/urls.inc index 4192f4a869..d8ffe91378 100644 --- a/ext/standard/tests/url/urls.inc +++ b/ext/standard/tests/url/urls.inc @@ -89,6 +89,7 @@ $urls = array( 'http://[x:80]/', '', '/', +'/rest/Users?filter={"id":"123"}', // Severely malformed URLs that do not parse: 'http:///blah.com', diff --git a/ext/standard/url.c b/ext/standard/url.c index 16237e6599..d8271a18ed 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -181,10 +181,6 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) p = e + 1; pp = p; - if (*s == '/' && *(s+1) == '/') { /* relative-scheme URL */ - s += 2; - } - while (pp-p < 6 && isdigit(*pp)) { pp++; } @@ -205,6 +201,10 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) STR_FREE(ret->scheme); efree(ret); return NULL; + } else if (*s == '/' && *(s+1) == '/') { /* relative-scheme URL */ + s += 2; + } else { + goto just_path; } } else if (*s == '/' && *(s+1) == '/') { /* relative-scheme URL */ s += 2; diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index ecacb76f94..70ee06eee4 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 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 | diff --git a/ext/standard/uuencode.c b/ext/standard/uuencode.c index 52e892ed9e..8544aef9f0 100644 --- a/ext/standard/uuencode.c +++ b/ext/standard/uuencode.c @@ -151,6 +151,9 @@ PHPAPI int php_uudecode(char *src, int src_len, char **dest) /* {{{ */ } while (s < ee) { + if(s+4 > e) { + goto err; + } *p++ = PHP_UU_DEC(*s) << 2 | PHP_UU_DEC(*(s + 1)) >> 4; *p++ = PHP_UU_DEC(*(s + 1)) << 4 | PHP_UU_DEC(*(s + 2)) >> 2; *p++ = PHP_UU_DEC(*(s + 2)) << 6 | PHP_UU_DEC(*(s + 3)); diff --git a/ext/standard/var.c b/ext/standard/var.c index 930edd6877..457f31db33 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -943,7 +943,7 @@ PHP_FUNCTION(serialize) } /* }}} */ -/* {{{ proto mixed unserialize(string variable_representation[, int &consumed]) +/* {{{ proto mixed unserialize(string variable_representation) Takes a string representation of variable and recreates it */ PHP_FUNCTION(unserialize) { @@ -951,9 +951,8 @@ PHP_FUNCTION(unserialize) int buf_len; const unsigned char *p; php_unserialize_data_t var_hash; - zval *consumed = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &buf, &buf_len, &consumed) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { RETURN_FALSE; } @@ -972,11 +971,6 @@ PHP_FUNCTION(unserialize) RETURN_FALSE; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - - if (consumed) { - zval_dtor(consumed); - ZVAL_LONG(consumed, ((char*)p) - buf); - } } /* }}} */ diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index 003bac9547..8b5392a9d7 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -4,7 +4,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 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 | diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index b3f5d29ca2..3a1b910953 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 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 | diff --git a/ext/tokenizer/tests/bug67395.phpt b/ext/tokenizer/tests/bug67395.phpt new file mode 100644 index 0000000000..c9b7f3012f --- /dev/null +++ b/ext/tokenizer/tests/bug67395.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug 67395: token_name() does not return name for T_POW and T_POW_EQUAL token +--FILE-- +<?php + +$powToken = token_get_all('<?php **')[1][0]; +var_dump(token_name($powToken)); + +$powEqualToken = token_get_all('<?php **=')[1][0]; +var_dump(token_name($powEqualToken)); + +?> +--EXPECT-- +string(5) "T_POW" +string(11) "T_POW_EQUAL" diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index dc48f040f1..beb9ea8e5b 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -39,6 +39,7 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) { 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_POW_EQUAL", T_POW_EQUAL, 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); @@ -70,6 +71,7 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) { REGISTER_LONG_CONSTANT("T_INT_CAST", T_INT_CAST, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_DEC", T_DEC, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_INC", T_INC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_POW", T_POW, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CLONE", T_CLONE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_NEW", T_NEW, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_EXIT", T_EXIT, CONST_CS | CONST_PERSISTENT); @@ -176,6 +178,7 @@ char *get_token_type_name(int token_type) case T_LOGICAL_AND: return "T_LOGICAL_AND"; case T_PRINT: return "T_PRINT"; case T_YIELD: return "T_YIELD"; + case T_POW_EQUAL: return "T_POW_EQUAL"; case T_SR_EQUAL: return "T_SR_EQUAL"; case T_SL_EQUAL: return "T_SL_EQUAL"; case T_XOR_EQUAL: return "T_XOR_EQUAL"; @@ -207,6 +210,7 @@ char *get_token_type_name(int token_type) case T_INT_CAST: return "T_INT_CAST"; case T_DEC: return "T_DEC"; case T_INC: return "T_INC"; + case T_POW: return "T_POW"; case T_CLONE: return "T_CLONE"; case T_NEW: return "T_NEW"; case T_EXIT: return "T_EXIT"; diff --git a/ext/zip/tests/oo_addglob.phpt b/ext/zip/tests/oo_addglob.phpt new file mode 100644 index 0000000000..970bfc7678 --- /dev/null +++ b/ext/zip/tests/oo_addglob.phpt @@ -0,0 +1,50 @@ +--TEST-- +ZipArchive::addGlob() method +--CREDITS-- +Sammy Kaye Powers <sammyk@sammykmedia.com> +w/Kenzo over the shoulder +#phptek Chicago 2014 +--SKIPIF-- +<?php +/* $Id$ */ +if(!extension_loaded('zip')) die('skip'); +?> +--FILE-- +<?php +$dirname = dirname(__FILE__) . '/'; +include $dirname . 'utils.inc'; +$file = $dirname . '__tmp_oo_addglob.zip'; + +copy($dirname . 'test.zip', $file); +touch($dirname . 'foo.txt'); +touch($dirname . 'bar.baz'); + +$zip = new ZipArchive(); +if (!$zip->open($file)) { + exit('failed'); +} +$options = array('add_path' => 'baz/', 'remove_all_path' => TRUE); +if (!$zip->addGlob($dirname . '*.{txt,baz}', GLOB_BRACE, $options)) { + echo "failed1\n"; +} +if ($zip->status == ZIPARCHIVE::ER_OK) { + dump_entries_name($zip); + $zip->close(); +} else { + echo "failed2\n"; +} +?> +--CLEAN-- +<?php +$dirname = dirname(__FILE__) . '/'; +unlink($dirname . '__tmp_oo_addglob.zip'); +unlink($dirname . 'foo.txt'); +unlink($dirname . 'bar.baz'); +?> +--EXPECTF-- +0 bar +1 foobar/ +2 foobar/baz +3 entry1.txt +4 baz/foo.txt +5 baz/bar.baz diff --git a/ext/zip/tests/oo_addpattern.phpt b/ext/zip/tests/oo_addpattern.phpt new file mode 100644 index 0000000000..4e1cab4ad9 --- /dev/null +++ b/ext/zip/tests/oo_addpattern.phpt @@ -0,0 +1,51 @@ +--TEST-- +ZipArchive::addPattern() method +--CREDITS-- +Sammy Kaye Powers <sammyk@sammykmedia.com> +w/Kenzo over the shoulder +#phptek Chicago 2014 +--SKIPIF-- +<?php +/* $Id$ */ +if(!extension_loaded('zip')) die('skip'); +?> +--FILE-- +<?php +$dirname = dirname(__FILE__) . '/'; +include $dirname . 'utils.inc'; +$file = $dirname . '__tmp_oo_addpattern.zip'; + +copy($dirname . 'test.zip', $file); +touch($dirname . 'foo.txt'); +touch($dirname . 'bar.txt'); + +$zip = new ZipArchive(); +if (!$zip->open($file)) { + exit('failed'); +} +$dir = realpath($dirname); +$options = array('add_path' => 'baz/', 'remove_path' => $dir); +if (!$zip->addPattern('/\.txt$/', $dir, $options)) { + echo "failed\n"; +} +if ($zip->status == ZIPARCHIVE::ER_OK) { + dump_entries_name($zip); + $zip->close(); +} else { + echo "failed\n"; +} +?> +--CLEAN-- +<?php +$dirname = dirname(__FILE__) . '/'; +unlink($dirname . '__tmp_oo_addpattern.zip'); +unlink($dirname . 'foo.txt'); +unlink($dirname . 'bar.txt'); +?> +--EXPECTF-- +0 bar +1 foobar/ +2 foobar/baz +3 entry1.txt +4 baz/bar.txt +5 baz/foo.txt diff --git a/ext/zlib/tests/gzseek_basic2.phpt b/ext/zlib/tests/gzseek_basic2.phpt index 82d305d0fb..8e037af139 100644 --- a/ext/zlib/tests/gzseek_basic2.phpt +++ b/ext/zlib/tests/gzseek_basic2.phpt @@ -24,7 +24,7 @@ gzclose($h); echo "\nreading the output file\n"; $h = gzopen($f, 'r'); echo gzread($h, strlen($str1))."\n"; -echo var_dump(bin2hex(gzread($h, 20))); +var_dump(bin2hex(gzread($h, 20))); echo gzread($h, strlen($str2))."\n"; gzclose($h); unlink($f); diff --git a/ext/zlib/tests/gzseek_variation1.phpt b/ext/zlib/tests/gzseek_variation1.phpt index b260783f11..8512b743bd 100644 --- a/ext/zlib/tests/gzseek_variation1.phpt +++ b/ext/zlib/tests/gzseek_variation1.phpt @@ -20,7 +20,7 @@ gzwrite($h, $str2); gzclose($h); $h = gzopen($f, 'r'); echo gzread($h, strlen($str1))."\n"; -echo var_dump(bin2hex(gzread($h, 20))); +var_dump(bin2hex(gzread($h, 20))); echo gzread($h, strlen($str2))."\n"; gzclose($h); unlink($f); diff --git a/ext/zlib/tests/gzseek_variation4.phpt b/ext/zlib/tests/gzseek_variation4.phpt index 3d0cf67ceb..529a012141 100644 --- a/ext/zlib/tests/gzseek_variation4.phpt +++ b/ext/zlib/tests/gzseek_variation4.phpt @@ -24,7 +24,7 @@ gzclose($h); echo "\nreading the output file\n"; $h = gzopen($f, 'r'); echo gzread($h, strlen($str1))."\n"; -echo var_dump(bin2hex(gzread($h, 20))); +var_dump(bin2hex(gzread($h, 20))); echo gzread($h, strlen($str2))."\n"; gzclose($h); unlink($f); diff --git a/ext/zlib/tests/gzseek_variation5.phpt b/ext/zlib/tests/gzseek_variation5.phpt index 93fb19fdbb..11e4912787 100644 --- a/ext/zlib/tests/gzseek_variation5.phpt +++ b/ext/zlib/tests/gzseek_variation5.phpt @@ -24,7 +24,7 @@ gzclose($h); echo "\nreading the output file\n"; $h = gzopen($f, 'r'); echo gzread($h, strlen($str1))."\n"; -echo var_dump(bin2hex(gzread($h, 20))); +var_dump(bin2hex(gzread($h, 20))); echo gzread($h, strlen($str2))."\n"; gzclose($h); unlink($f); @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 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 | diff --git a/main/SAPI.c b/main/SAPI.c index 8c347cb6d4..b69143c587 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -279,7 +279,7 @@ SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data) } - SG(request_info).request_body = php_stream_temp_create(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE); + SG(request_info).request_body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir)); if (sapi_module.read_post) { int read_bytes; @@ -462,7 +462,7 @@ SAPI_API void sapi_activate(TSRMLS_D) SG(request_info).post_entry = NULL; SG(request_info).proto_num = 1000; /* Default to HTTP 1.0 */ SG(global_request_time) = 0; - + SG(post_read) = 0; /* It's possible to override this general case in the activate() callback, if necessary. */ if (SG(request_info).request_method && !strcmp(SG(request_info).request_method, "HEAD")) { SG(request_info).headers_only = 1; @@ -825,7 +825,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) "0", sizeof("0") - 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); } else if (!STRCASECMP(header_line, "Location")) { if ((SG(sapi_headers).http_response_code < 300 || - SG(sapi_headers).http_response_code > 307) && + SG(sapi_headers).http_response_code > 399) && SG(sapi_headers).http_response_code != 201) { /* Return a Found Redirect if one is not already specified */ if (http_response_code) { /* user specified redirect code */ diff --git a/main/php_memory_streams.h b/main/php_memory_streams.h index 3c4c3280eb..229ed1902e 100644 --- a/main/php_memory_streams.h +++ b/main/php_memory_streams.h @@ -36,6 +36,7 @@ #define php_stream_temp_new() php_stream_temp_create(TEMP_STREAM_DEFAULT, PHP_STREAM_MAX_MEM) #define php_stream_temp_create(mode, max_memory_usage) _php_stream_temp_create((mode), (max_memory_usage) STREAMS_CC TSRMLS_CC) +#define php_stream_temp_create_ex(mode, max_memory_usage, tmpdir) _php_stream_temp_create_ex((mode), (max_memory_usage), (tmpdir) STREAMS_CC TSRMLS_CC) #define php_stream_temp_create_rel(mode, max_memory_usage) _php_stream_temp_create((mode), (max_memory_usage) STREAMS_REL_CC TSRMLS_CC) #define php_stream_temp_open(mode, max_memory_usage, buf, length) _php_stream_temp_open((mode), (max_memory_usage), (buf), (length) STREAMS_CC TSRMLS_CC) @@ -45,6 +46,7 @@ PHPAPI php_stream *_php_stream_memory_open(int mode, char *buf, size_t length ST PHPAPI char *_php_stream_memory_get_buffer(php_stream *stream, size_t *length STREAMS_DC TSRMLS_DC); PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC TSRMLS_DC); +PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, const char *tmpdir STREAMS_DC TSRMLS_DC); PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC TSRMLS_DC); END_EXTERN_C() diff --git a/main/php_streams.h b/main/php_streams.h index aa4c05c54f..d1efa71988 100644 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -373,6 +373,7 @@ END_EXTERN_C() /* Flags for url_stat method in wrapper ops */ #define PHP_STREAM_URL_STAT_LINK 1 #define PHP_STREAM_URL_STAT_QUIET 2 +#define PHP_STREAM_URL_STAT_NOCACHE 4 /* change the blocking mode of stream: value == 1 => blocking, value == 0 => non-blocking. */ #define PHP_STREAM_OPTION_BLOCKING 1 diff --git a/main/php_variables.c b/main/php_variables.c index cf8cdcfb86..fef905ff7d 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -694,7 +694,7 @@ static zend_bool php_auto_globals_create_request(const char *name, uint name_len /* {{{ php_hash_environment */ -int php_hash_environment(TSRMLS_D) +PHPAPI int php_hash_environment(TSRMLS_D) { memset(PG(http_globals), 0, sizeof(PG(http_globals))); zend_activate_auto_globals(TSRMLS_C); diff --git a/main/php_variables.h b/main/php_variables.h index 37b2cf2a04..2331c582e6 100644 --- a/main/php_variables.h +++ b/main/php_variables.h @@ -41,7 +41,7 @@ PHPAPI void php_register_variable(char *var, char *val, zval *track_vars_array T PHPAPI void php_register_variable_safe(char *var, char *val, int val_len, zval *track_vars_array TSRMLS_DC); PHPAPI void php_register_variable_ex(char *var, zval *val, zval *track_vars_array TSRMLS_DC); -int php_hash_environment(TSRMLS_D); +PHPAPI int php_hash_environment(TSRMLS_D); END_EXTERN_C() #define NUM_TRACK_VARS 6 diff --git a/main/streams/memory.c b/main/streams/memory.c index 854b9e2720..09421ea49d 100644 --- a/main/streams/memory.c +++ b/main/streams/memory.c @@ -352,6 +352,7 @@ typedef struct { size_t smax; int mode; zval* meta; + char* tmpdir; } php_stream_temp_data; @@ -369,7 +370,7 @@ static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t char *membuf = php_stream_memory_get_buffer(ts->innerstream, &memsize); if (memsize + count >= ts->smax) { - php_stream *file = php_stream_fopen_tmpfile(); + php_stream *file = php_stream_fopen_temporary_file(ts->tmpdir, "php", NULL); php_stream_write(file, membuf, memsize); php_stream_free_enclosed(ts->innerstream, PHP_STREAM_FREE_CLOSE); ts->innerstream = file; @@ -420,6 +421,10 @@ static int php_stream_temp_close(php_stream *stream, int close_handle TSRMLS_DC) zval_ptr_dtor(&ts->meta); } + if (ts->tmpdir) { + efree(ts->tmpdir); + } + efree(ts); return ret; @@ -547,8 +552,8 @@ PHPAPI php_stream_ops php_stream_temp_ops = { /* }}} */ -/* {{{ _php_stream_temp_create */ -PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC TSRMLS_DC) +/* {{{ _php_stream_temp_create_ex */ +PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, const char *tmpdir STREAMS_DC TSRMLS_DC) { php_stream_temp_data *self; php_stream *stream; @@ -556,7 +561,9 @@ PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STR self = ecalloc(1, sizeof(*self)); self->smax = max_memory_usage; self->mode = mode; - self->meta = NULL; + if (tmpdir) { + self->tmpdir = estrdup(tmpdir); + } stream = php_stream_alloc_rel(&php_stream_temp_ops, self, 0, mode & TEMP_STREAM_READONLY ? "rb" : "w+b"); stream->flags |= PHP_STREAM_FLAG_NO_BUFFER; self->innerstream = php_stream_memory_create_rel(mode); @@ -566,6 +573,12 @@ PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STR } /* }}} */ +/* {{{ _php_stream_temp_create */ +PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC TSRMLS_DC) +{ + return php_stream_temp_create_ex(mode, max_memory_usage, NULL); +} +/* }}} */ /* {{{ _php_stream_temp_open */ PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC TSRMLS_DC) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 5e9e5c7ace..87312b9ef8 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -183,31 +183,20 @@ static php_stream *_php_stream_fopen_from_file_int(FILE *file, const char *mode return php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode); } -PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path_ptr STREAMS_DC TSRMLS_DC) { - int fd = php_open_temporary_fd(dir, pfx, opened_path TSRMLS_CC); + char *opened_path = NULL; + int fd; + fd = php_open_temporary_fd(dir, pfx, &opened_path TSRMLS_CC); if (fd != -1) { - php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL); - if (stream) { - return stream; - } - close(fd); - - php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to allocate stream"); - - return NULL; - } - return NULL; -} + php_stream *stream; -PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC) -{ - char *opened_path = NULL; - int fd = php_open_temporary_fd(NULL, "php", &opened_path TSRMLS_CC); + if (opened_path_ptr) { + *opened_path_ptr = opened_path; + } - if (fd != -1) { - php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL); + stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL); if (stream) { php_stdio_stream_data *self = (php_stdio_stream_data*)stream->abstract; stream->wrapper = &php_plain_files_wrapper; @@ -227,6 +216,11 @@ PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC) return NULL; } +PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC) +{ + return php_stream_fopen_temporary_file(NULL, "php", NULL); +} + PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC TSRMLS_DC) { php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, mode, persistent_id); diff --git a/main/streams/streams.c b/main/streams/streams.c index c7ff1210a8..6716dce524 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1924,16 +1924,18 @@ PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf const char *path_to_open = path; int ret; - /* Try to hit the cache first */ - if (flags & PHP_STREAM_URL_STAT_LINK) { - if (BG(CurrentLStatFile) && strcmp(path, BG(CurrentLStatFile)) == 0) { - memcpy(ssb, &BG(lssb), sizeof(php_stream_statbuf)); - return 0; - } - } else { - if (BG(CurrentStatFile) && strcmp(path, BG(CurrentStatFile)) == 0) { - memcpy(ssb, &BG(ssb), sizeof(php_stream_statbuf)); - return 0; + if (!(flags & PHP_STREAM_URL_STAT_NOCACHE)) { + /* Try to hit the cache first */ + if (flags & PHP_STREAM_URL_STAT_LINK) { + if (BG(CurrentLStatFile) && strcmp(path, BG(CurrentLStatFile)) == 0) { + memcpy(ssb, &BG(lssb), sizeof(php_stream_statbuf)); + return 0; + } + } else { + if (BG(CurrentStatFile) && strcmp(path, BG(CurrentStatFile)) == 0) { + memcpy(ssb, &BG(ssb), sizeof(php_stream_statbuf)); + return 0; + } } } @@ -1941,19 +1943,21 @@ PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf if (wrapper && wrapper->wops->url_stat) { ret = wrapper->wops->url_stat(wrapper, path_to_open, flags, ssb, context TSRMLS_CC); if (ret == 0) { - /* Drop into cache */ - if (flags & PHP_STREAM_URL_STAT_LINK) { - if (BG(CurrentLStatFile)) { - efree(BG(CurrentLStatFile)); - } - BG(CurrentLStatFile) = estrdup(path); - memcpy(&BG(lssb), ssb, sizeof(php_stream_statbuf)); - } else { - if (BG(CurrentStatFile)) { - efree(BG(CurrentStatFile)); + if (!(flags & PHP_STREAM_URL_STAT_NOCACHE)) { + /* Drop into cache */ + if (flags & PHP_STREAM_URL_STAT_LINK) { + if (BG(CurrentLStatFile)) { + efree(BG(CurrentLStatFile)); + } + BG(CurrentLStatFile) = estrdup(path); + memcpy(&BG(lssb), ssb, sizeof(php_stream_statbuf)); + } else { + if (BG(CurrentStatFile)) { + efree(BG(CurrentStatFile)); + } + BG(CurrentStatFile) = estrdup(path); + memcpy(&BG(ssb), ssb, sizeof(php_stream_statbuf)); } - BG(CurrentStatFile) = estrdup(path); - memcpy(&BG(ssb), ssb, sizeof(php_stream_statbuf)); } } return ret; diff --git a/run-tests.php b/run-tests.php index 56aa123bac..e6a7e1b806 100755 --- a/run-tests.php +++ b/run-tests.php @@ -581,8 +581,8 @@ if (isset($argc) && $argc > 1) { if (!$valgrind_header) { error("Valgrind returned no version info, cannot proceed.\nPlease check if Valgrind is installed."); } else { - $valgrind_version = preg_replace("/valgrind-(\d)\.(\d)\.(\d+)([.\w_-]+)?(\s+)/", '$1$2$3', $valgrind_header, 1, $replace_count); - if ($replace_count != 1 || !is_numeric($valgrind_version)) { + $valgrind_version = preg_replace("/valgrind-(\d+)\.(\d+)\.(\d+)([.\w_-]+)?(\s+)/", '$1.$2.$3', $valgrind_header, 1, $replace_count); + if ($replace_count != 1) { error("Valgrind returned invalid version info (\"$valgrind_header\"), cannot proceed."); } $valgrind_header = trim($valgrind_header); @@ -1359,6 +1359,7 @@ TEST $file } else { show_result('SKIP', $tested, $tested_file, "reason: CGI not available"); + junit_init_suite(junit_get_suitename_for($shortname)); junit_mark_test_as('SKIP', $shortname, $tested, 0, 'CGI not available'); return 'SKIPPED'; } @@ -1538,7 +1539,7 @@ TEST $file } $message = !empty($m[1]) ? $m[1] : ''; - junit_mark_test_as('SKIP', $shortname, $tested, null, "<![CDATA[\n$message\n]]>"); + junit_mark_test_as('SKIP', $shortname, $tested, null, $message); return 'SKIPPED'; } @@ -1563,7 +1564,7 @@ TEST $file ) { $message = "ext/zlib required"; show_result('SKIP', $tested, $tested_file, "reason: $message", $temp_filenames); - junit_mark_test_as('SKIP', $shortname, $tested, null, "<![CDATA[\n$message\n]]>"); + junit_mark_test_as('SKIP', $shortname, $tested, null, $message); return 'SKIPPED'; } @@ -1787,7 +1788,7 @@ TEST $file $env['USE_ZEND_ALLOC'] = '0'; $env['ZEND_DONT_UNLOAD_MODULES'] = 1; - if ($valgrind_version >= 330) { + if (version_compare($valgrind_version, '3.3.0', '>=')) { /* valgrind 3.3.0+ doesn't have --log-file-exactly option */ $cmd = "valgrind -q --tool=memcheck --trace-children=yes --log-file=$memcheck_filename $cmd"; } else { @@ -2131,7 +2132,7 @@ $output $php = $old_php; } - $diff = empty($diff) ? '' : "<![CDATA[\n " . preg_replace('/\e/', '<esc>', $diff) . "\n]]>"; + $diff = empty($diff) ? '' : preg_replace('/\e/', '<esc>', $diff); junit_mark_test_as($restype, str_replace($cwd . '/', '', $tested_file), $tested, null, $info, $diff); @@ -2710,6 +2711,10 @@ function junit_mark_test_as($type, $file_name, $test_name, $time = null, $messag junit_suite_record($suite, 'execution_time', $time); $escaped_details = htmlspecialchars($details, ENT_QUOTES, 'UTF-8'); + $escaped_details = preg_replace_callback('/[\0-\x08\x0B\x0C\x0E-\x1F]/', function ($c) { + return sprintf('[[0x%02x]]', ord($c[0])); + }, $escaped_details); + $escaped_message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8'); $escaped_test_name = basename($file_name) . ' - ' . htmlspecialchars($test_name, ENT_QUOTES); $JUNIT['files'][$file_name]['xml'] = "<testcase classname='$suite' name='$escaped_test_name' time='$time'>\n"; @@ -2726,16 +2731,16 @@ function junit_mark_test_as($type, $file_name, $test_name, $time = null, $messag junit_suite_record($suite, 'test_pass'); } elseif ('BORK' == $type) { junit_suite_record($suite, 'test_error'); - $JUNIT['files'][$file_name]['xml'] .= "<error type='$output_type' message='$message'/>\n"; + $JUNIT['files'][$file_name]['xml'] .= "<error type='$output_type' message='$escaped_message'/>\n"; } elseif ('SKIP' == $type) { junit_suite_record($suite, 'test_skip'); - $JUNIT['files'][$file_name]['xml'] .= "<skipped>$message</skipped>\n"; + $JUNIT['files'][$file_name]['xml'] .= "<skipped>$escaped_message</skipped>\n"; } elseif('FAIL' == $type) { junit_suite_record($suite, 'test_fail'); - $JUNIT['files'][$file_name]['xml'] .= "<failure type='$output_type' message='$message'>$escaped_details</failure>\n"; + $JUNIT['files'][$file_name]['xml'] .= "<failure type='$output_type' message='$escaped_message'>$escaped_details</failure>\n"; } else { junit_suite_record($suite, 'test_error'); - $JUNIT['files'][$file_name]['xml'] .= "<error type='$output_type' message='$message'>$escaped_details</error>\n"; + $JUNIT['files'][$file_name]['xml'] .= "<error type='$output_type' message='$escaped_message'>$escaped_details</error>\n"; } $JUNIT['files'][$file_name]['xml'] .= "</testcase>\n"; diff --git a/sapi/cli/generate_mime_type_map.php b/sapi/cli/generate_mime_type_map.php new file mode 100644 index 0000000000..4475004985 --- /dev/null +++ b/sapi/cli/generate_mime_type_map.php @@ -0,0 +1,76 @@ +#!/usr/bin/env php +<?php + +// Check if we are being given a mime.types file or if we should use the +// default URL. +$source = count($_SERVER['argv']) > 1 ? $_SERVER['argv'][1] : 'https://raw.githubusercontent.com/apache/httpd/trunk/docs/conf/mime.types'; + +// See if we can actually load it. +$types = @file($source); +if ($types === false) { + fprintf(STDERR, "Error: unable to read $source\n"); + exit(1); +} + +// Remove comments and flip into an extensions array. +$extensions = []; +array_walk($types, function ($line) use (&$extensions) { + $line = trim($line); + if ($line && $line[0] != '#') { + $fields = preg_split('/\s+/', $line); + if (count($fields) > 1) { + $mime = array_shift($fields); + foreach ($fields as $extension) { + $extensions[$extension] = $mime; + } + } + } +}); + +?> +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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: Moriyoshi Koizumi <moriyoshi@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* This is a generated file. Rather than modifying it, please run + * "php generate_mime_type_map.php > mime_type_map.h" to regenerate the file. */ + +#ifndef PHP_CLI_SERVER_MIME_TYPE_MAP_H +#define PHP_CLI_SERVER_MIME_TYPE_MAP_H + +typedef struct php_cli_server_ext_mime_type_pair { + const char *ext; + const char *mime_type; +} php_cli_server_ext_mime_type_pair; + +static php_cli_server_ext_mime_type_pair mime_type_map[] = { +<?php foreach ($extensions as $extension => $mime): ?> + { "<?= addcslashes($extension, "\0..\37!@\@\177..\377") ?>", "<?= addcslashes($mime, "\0..\37!@\@\177..\377") ?>" }, +<?php endforeach ?> + { NULL, NULL } +}; + +#endif /* PHP_CLI_SERVER_MIME_TYPE_MAP_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/sapi/cli/mime_type_map.h b/sapi/cli/mime_type_map.h new file mode 100644 index 0000000000..72c05d4149 --- /dev/null +++ b/sapi/cli/mime_type_map.h @@ -0,0 +1,1024 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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: Moriyoshi Koizumi <moriyoshi@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* This is a generated file. Rather than modifying it, please run + * "php generate_mime_type_map.php > mime_type_map.h" to regenerate the file. */ + +#ifndef PHP_CLI_SERVER_MIME_TYPE_MAP_H +#define PHP_CLI_SERVER_MIME_TYPE_MAP_H + +typedef struct php_cli_server_ext_mime_type_pair { + const char *ext; + const char *mime_type; +} php_cli_server_ext_mime_type_pair; + +static php_cli_server_ext_mime_type_pair mime_type_map[] = { + { "ez", "application/andrew-inset" }, + { "aw", "application/applixware" }, + { "atom", "application/atom+xml" }, + { "atomcat", "application/atomcat+xml" }, + { "atomsvc", "application/atomsvc+xml" }, + { "ccxml", "application/ccxml+xml" }, + { "cdmia", "application/cdmi-capability" }, + { "cdmic", "application/cdmi-container" }, + { "cdmid", "application/cdmi-domain" }, + { "cdmio", "application/cdmi-object" }, + { "cdmiq", "application/cdmi-queue" }, + { "cu", "application/cu-seeme" }, + { "davmount", "application/davmount+xml" }, + { "dbk", "application/docbook+xml" }, + { "dssc", "application/dssc+der" }, + { "xdssc", "application/dssc+xml" }, + { "ecma", "application/ecmascript" }, + { "emma", "application/emma+xml" }, + { "epub", "application/epub+zip" }, + { "exi", "application/exi" }, + { "pfr", "application/font-tdpfr" }, + { "gml", "application/gml+xml" }, + { "gpx", "application/gpx+xml" }, + { "gxf", "application/gxf" }, + { "stk", "application/hyperstudio" }, + { "ink", "application/inkml+xml" }, + { "inkml", "application/inkml+xml" }, + { "ipfix", "application/ipfix" }, + { "jar", "application/java-archive" }, + { "ser", "application/java-serialized-object" }, + { "class", "application/java-vm" }, + { "js", "application/javascript" }, + { "json", "application/json" }, + { "jsonml", "application/jsonml+json" }, + { "lostxml", "application/lost+xml" }, + { "hqx", "application/mac-binhex40" }, + { "cpt", "application/mac-compactpro" }, + { "mads", "application/mads+xml" }, + { "mrc", "application/marc" }, + { "mrcx", "application/marcxml+xml" }, + { "ma", "application/mathematica" }, + { "nb", "application/mathematica" }, + { "mb", "application/mathematica" }, + { "mathml", "application/mathml+xml" }, + { "mbox", "application/mbox" }, + { "mscml", "application/mediaservercontrol+xml" }, + { "metalink", "application/metalink+xml" }, + { "meta4", "application/metalink4+xml" }, + { "mets", "application/mets+xml" }, + { "mods", "application/mods+xml" }, + { "m21", "application/mp21" }, + { "mp21", "application/mp21" }, + { "mp4s", "application/mp4" }, + { "doc", "application/msword" }, + { "dot", "application/msword" }, + { "mxf", "application/mxf" }, + { "bin", "application/octet-stream" }, + { "dms", "application/octet-stream" }, + { "lrf", "application/octet-stream" }, + { "mar", "application/octet-stream" }, + { "so", "application/octet-stream" }, + { "dist", "application/octet-stream" }, + { "distz", "application/octet-stream" }, + { "pkg", "application/octet-stream" }, + { "bpk", "application/octet-stream" }, + { "dump", "application/octet-stream" }, + { "elc", "application/octet-stream" }, + { "deploy", "application/octet-stream" }, + { "oda", "application/oda" }, + { "opf", "application/oebps-package+xml" }, + { "ogx", "application/ogg" }, + { "omdoc", "application/omdoc+xml" }, + { "onetoc", "application/onenote" }, + { "onetoc2", "application/onenote" }, + { "onetmp", "application/onenote" }, + { "onepkg", "application/onenote" }, + { "oxps", "application/oxps" }, + { "xer", "application/patch-ops-error+xml" }, + { "pdf", "application/pdf" }, + { "pgp", "application/pgp-encrypted" }, + { "asc", "application/pgp-signature" }, + { "sig", "application/pgp-signature" }, + { "prf", "application/pics-rules" }, + { "p10", "application/pkcs10" }, + { "p7m", "application/pkcs7-mime" }, + { "p7c", "application/pkcs7-mime" }, + { "p7s", "application/pkcs7-signature" }, + { "p8", "application/pkcs8" }, + { "ac", "application/pkix-attr-cert" }, + { "cer", "application/pkix-cert" }, + { "crl", "application/pkix-crl" }, + { "pkipath", "application/pkix-pkipath" }, + { "pki", "application/pkixcmp" }, + { "pls", "application/pls+xml" }, + { "ai", "application/postscript" }, + { "eps", "application/postscript" }, + { "ps", "application/postscript" }, + { "cww", "application/prs.cww" }, + { "pskcxml", "application/pskc+xml" }, + { "rdf", "application/rdf+xml" }, + { "rif", "application/reginfo+xml" }, + { "rnc", "application/relax-ng-compact-syntax" }, + { "rl", "application/resource-lists+xml" }, + { "rld", "application/resource-lists-diff+xml" }, + { "rs", "application/rls-services+xml" }, + { "gbr", "application/rpki-ghostbusters" }, + { "mft", "application/rpki-manifest" }, + { "roa", "application/rpki-roa" }, + { "rsd", "application/rsd+xml" }, + { "rss", "application/rss+xml" }, + { "rtf", "application/rtf" }, + { "sbml", "application/sbml+xml" }, + { "scq", "application/scvp-cv-request" }, + { "scs", "application/scvp-cv-response" }, + { "spq", "application/scvp-vp-request" }, + { "spp", "application/scvp-vp-response" }, + { "sdp", "application/sdp" }, + { "setpay", "application/set-payment-initiation" }, + { "setreg", "application/set-registration-initiation" }, + { "shf", "application/shf+xml" }, + { "smi", "application/smil+xml" }, + { "smil", "application/smil+xml" }, + { "rq", "application/sparql-query" }, + { "srx", "application/sparql-results+xml" }, + { "gram", "application/srgs" }, + { "grxml", "application/srgs+xml" }, + { "sru", "application/sru+xml" }, + { "ssdl", "application/ssdl+xml" }, + { "ssml", "application/ssml+xml" }, + { "tei", "application/tei+xml" }, + { "teicorpus", "application/tei+xml" }, + { "tfi", "application/thraud+xml" }, + { "tsd", "application/timestamped-data" }, + { "plb", "application/vnd.3gpp.pic-bw-large" }, + { "psb", "application/vnd.3gpp.pic-bw-small" }, + { "pvb", "application/vnd.3gpp.pic-bw-var" }, + { "tcap", "application/vnd.3gpp2.tcap" }, + { "pwn", "application/vnd.3m.post-it-notes" }, + { "aso", "application/vnd.accpac.simply.aso" }, + { "imp", "application/vnd.accpac.simply.imp" }, + { "acu", "application/vnd.acucobol" }, + { "atc", "application/vnd.acucorp" }, + { "acutc", "application/vnd.acucorp" }, + { "air", "application/vnd.adobe.air-application-installer-package+zip" }, + { "fcdt", "application/vnd.adobe.formscentral.fcdt" }, + { "fxp", "application/vnd.adobe.fxp" }, + { "fxpl", "application/vnd.adobe.fxp" }, + { "xdp", "application/vnd.adobe.xdp+xml" }, + { "xfdf", "application/vnd.adobe.xfdf" }, + { "ahead", "application/vnd.ahead.space" }, + { "azf", "application/vnd.airzip.filesecure.azf" }, + { "azs", "application/vnd.airzip.filesecure.azs" }, + { "azw", "application/vnd.amazon.ebook" }, + { "acc", "application/vnd.americandynamics.acc" }, + { "ami", "application/vnd.amiga.ami" }, + { "apk", "application/vnd.android.package-archive" }, + { "cii", "application/vnd.anser-web-certificate-issue-initiation" }, + { "fti", "application/vnd.anser-web-funds-transfer-initiation" }, + { "atx", "application/vnd.antix.game-component" }, + { "mpkg", "application/vnd.apple.installer+xml" }, + { "m3u8", "application/vnd.apple.mpegurl" }, + { "swi", "application/vnd.aristanetworks.swi" }, + { "iota", "application/vnd.astraea-software.iota" }, + { "aep", "application/vnd.audiograph" }, + { "mpm", "application/vnd.blueice.multipass" }, + { "bmi", "application/vnd.bmi" }, + { "rep", "application/vnd.businessobjects" }, + { "cdxml", "application/vnd.chemdraw+xml" }, + { "mmd", "application/vnd.chipnuts.karaoke-mmd" }, + { "cdy", "application/vnd.cinderella" }, + { "cla", "application/vnd.claymore" }, + { "rp9", "application/vnd.cloanto.rp9" }, + { "c4g", "application/vnd.clonk.c4group" }, + { "c4d", "application/vnd.clonk.c4group" }, + { "c4f", "application/vnd.clonk.c4group" }, + { "c4p", "application/vnd.clonk.c4group" }, + { "c4u", "application/vnd.clonk.c4group" }, + { "c11amc", "application/vnd.cluetrust.cartomobile-config" }, + { "c11amz", "application/vnd.cluetrust.cartomobile-config-pkg" }, + { "csp", "application/vnd.commonspace" }, + { "cdbcmsg", "application/vnd.contact.cmsg" }, + { "cmc", "application/vnd.cosmocaller" }, + { "clkx", "application/vnd.crick.clicker" }, + { "clkk", "application/vnd.crick.clicker.keyboard" }, + { "clkp", "application/vnd.crick.clicker.palette" }, + { "clkt", "application/vnd.crick.clicker.template" }, + { "clkw", "application/vnd.crick.clicker.wordbank" }, + { "wbs", "application/vnd.criticaltools.wbs+xml" }, + { "pml", "application/vnd.ctc-posml" }, + { "ppd", "application/vnd.cups-ppd" }, + { "car", "application/vnd.curl.car" }, + { "pcurl", "application/vnd.curl.pcurl" }, + { "dart", "application/vnd.dart" }, + { "rdz", "application/vnd.data-vision.rdz" }, + { "uvf", "application/vnd.dece.data" }, + { "uvvf", "application/vnd.dece.data" }, + { "uvd", "application/vnd.dece.data" }, + { "uvvd", "application/vnd.dece.data" }, + { "uvt", "application/vnd.dece.ttml+xml" }, + { "uvvt", "application/vnd.dece.ttml+xml" }, + { "uvx", "application/vnd.dece.unspecified" }, + { "uvvx", "application/vnd.dece.unspecified" }, + { "uvz", "application/vnd.dece.zip" }, + { "uvvz", "application/vnd.dece.zip" }, + { "fe_launch", "application/vnd.denovo.fcselayout-link" }, + { "dna", "application/vnd.dna" }, + { "mlp", "application/vnd.dolby.mlp" }, + { "dpg", "application/vnd.dpgraph" }, + { "dfac", "application/vnd.dreamfactory" }, + { "kpxx", "application/vnd.ds-keypoint" }, + { "ait", "application/vnd.dvb.ait" }, + { "svc", "application/vnd.dvb.service" }, + { "geo", "application/vnd.dynageo" }, + { "mag", "application/vnd.ecowin.chart" }, + { "nml", "application/vnd.enliven" }, + { "esf", "application/vnd.epson.esf" }, + { "msf", "application/vnd.epson.msf" }, + { "qam", "application/vnd.epson.quickanime" }, + { "slt", "application/vnd.epson.salt" }, + { "ssf", "application/vnd.epson.ssf" }, + { "es3", "application/vnd.eszigno3+xml" }, + { "et3", "application/vnd.eszigno3+xml" }, + { "ez2", "application/vnd.ezpix-album" }, + { "ez3", "application/vnd.ezpix-package" }, + { "fdf", "application/vnd.fdf" }, + { "mseed", "application/vnd.fdsn.mseed" }, + { "seed", "application/vnd.fdsn.seed" }, + { "dataless", "application/vnd.fdsn.seed" }, + { "gph", "application/vnd.flographit" }, + { "ftc", "application/vnd.fluxtime.clip" }, + { "fm", "application/vnd.framemaker" }, + { "frame", "application/vnd.framemaker" }, + { "maker", "application/vnd.framemaker" }, + { "book", "application/vnd.framemaker" }, + { "fnc", "application/vnd.frogans.fnc" }, + { "ltf", "application/vnd.frogans.ltf" }, + { "fsc", "application/vnd.fsc.weblaunch" }, + { "oas", "application/vnd.fujitsu.oasys" }, + { "oa2", "application/vnd.fujitsu.oasys2" }, + { "oa3", "application/vnd.fujitsu.oasys3" }, + { "fg5", "application/vnd.fujitsu.oasysgp" }, + { "bh2", "application/vnd.fujitsu.oasysprs" }, + { "ddd", "application/vnd.fujixerox.ddd" }, + { "xdw", "application/vnd.fujixerox.docuworks" }, + { "xbd", "application/vnd.fujixerox.docuworks.binder" }, + { "fzs", "application/vnd.fuzzysheet" }, + { "txd", "application/vnd.genomatix.tuxedo" }, + { "ggb", "application/vnd.geogebra.file" }, + { "ggt", "application/vnd.geogebra.tool" }, + { "gex", "application/vnd.geometry-explorer" }, + { "gre", "application/vnd.geometry-explorer" }, + { "gxt", "application/vnd.geonext" }, + { "g2w", "application/vnd.geoplan" }, + { "g3w", "application/vnd.geospace" }, + { "gmx", "application/vnd.gmx" }, + { "kml", "application/vnd.google-earth.kml+xml" }, + { "kmz", "application/vnd.google-earth.kmz" }, + { "gqf", "application/vnd.grafeq" }, + { "gqs", "application/vnd.grafeq" }, + { "gac", "application/vnd.groove-account" }, + { "ghf", "application/vnd.groove-help" }, + { "gim", "application/vnd.groove-identity-message" }, + { "grv", "application/vnd.groove-injector" }, + { "gtm", "application/vnd.groove-tool-message" }, + { "tpl", "application/vnd.groove-tool-template" }, + { "vcg", "application/vnd.groove-vcard" }, + { "hal", "application/vnd.hal+xml" }, + { "zmm", "application/vnd.handheld-entertainment+xml" }, + { "hbci", "application/vnd.hbci" }, + { "les", "application/vnd.hhe.lesson-player" }, + { "hpgl", "application/vnd.hp-hpgl" }, + { "hpid", "application/vnd.hp-hpid" }, + { "hps", "application/vnd.hp-hps" }, + { "jlt", "application/vnd.hp-jlyt" }, + { "pcl", "application/vnd.hp-pcl" }, + { "pclxl", "application/vnd.hp-pclxl" }, + { "sfd-hdstx", "application/vnd.hydrostatix.sof-data" }, + { "mpy", "application/vnd.ibm.minipay" }, + { "afp", "application/vnd.ibm.modcap" }, + { "listafp", "application/vnd.ibm.modcap" }, + { "list3820", "application/vnd.ibm.modcap" }, + { "irm", "application/vnd.ibm.rights-management" }, + { "sc", "application/vnd.ibm.secure-container" }, + { "icc", "application/vnd.iccprofile" }, + { "icm", "application/vnd.iccprofile" }, + { "igl", "application/vnd.igloader" }, + { "ivp", "application/vnd.immervision-ivp" }, + { "ivu", "application/vnd.immervision-ivu" }, + { "igm", "application/vnd.insors.igm" }, + { "xpw", "application/vnd.intercon.formnet" }, + { "xpx", "application/vnd.intercon.formnet" }, + { "i2g", "application/vnd.intergeo" }, + { "qbo", "application/vnd.intu.qbo" }, + { "qfx", "application/vnd.intu.qfx" }, + { "rcprofile", "application/vnd.ipunplugged.rcprofile" }, + { "irp", "application/vnd.irepository.package+xml" }, + { "xpr", "application/vnd.is-xpr" }, + { "fcs", "application/vnd.isac.fcs" }, + { "jam", "application/vnd.jam" }, + { "rms", "application/vnd.jcp.javame.midlet-rms" }, + { "jisp", "application/vnd.jisp" }, + { "joda", "application/vnd.joost.joda-archive" }, + { "ktz", "application/vnd.kahootz" }, + { "ktr", "application/vnd.kahootz" }, + { "karbon", "application/vnd.kde.karbon" }, + { "chrt", "application/vnd.kde.kchart" }, + { "kfo", "application/vnd.kde.kformula" }, + { "flw", "application/vnd.kde.kivio" }, + { "kon", "application/vnd.kde.kontour" }, + { "kpr", "application/vnd.kde.kpresenter" }, + { "kpt", "application/vnd.kde.kpresenter" }, + { "ksp", "application/vnd.kde.kspread" }, + { "kwd", "application/vnd.kde.kword" }, + { "kwt", "application/vnd.kde.kword" }, + { "htke", "application/vnd.kenameaapp" }, + { "kia", "application/vnd.kidspiration" }, + { "kne", "application/vnd.kinar" }, + { "knp", "application/vnd.kinar" }, + { "skp", "application/vnd.koan" }, + { "skd", "application/vnd.koan" }, + { "skt", "application/vnd.koan" }, + { "skm", "application/vnd.koan" }, + { "sse", "application/vnd.kodak-descriptor" }, + { "lasxml", "application/vnd.las.las+xml" }, + { "lbd", "application/vnd.llamagraphics.life-balance.desktop" }, + { "lbe", "application/vnd.llamagraphics.life-balance.exchange+xml" }, + { "123", "application/vnd.lotus-1-2-3" }, + { "apr", "application/vnd.lotus-approach" }, + { "pre", "application/vnd.lotus-freelance" }, + { "nsf", "application/vnd.lotus-notes" }, + { "org", "application/vnd.lotus-organizer" }, + { "scm", "application/vnd.lotus-screencam" }, + { "lwp", "application/vnd.lotus-wordpro" }, + { "portpkg", "application/vnd.macports.portpkg" }, + { "mcd", "application/vnd.mcd" }, + { "mc1", "application/vnd.medcalcdata" }, + { "cdkey", "application/vnd.mediastation.cdkey" }, + { "mwf", "application/vnd.mfer" }, + { "mfm", "application/vnd.mfmp" }, + { "flo", "application/vnd.micrografx.flo" }, + { "igx", "application/vnd.micrografx.igx" }, + { "mif", "application/vnd.mif" }, + { "daf", "application/vnd.mobius.daf" }, + { "dis", "application/vnd.mobius.dis" }, + { "mbk", "application/vnd.mobius.mbk" }, + { "mqy", "application/vnd.mobius.mqy" }, + { "msl", "application/vnd.mobius.msl" }, + { "plc", "application/vnd.mobius.plc" }, + { "txf", "application/vnd.mobius.txf" }, + { "mpn", "application/vnd.mophun.application" }, + { "mpc", "application/vnd.mophun.certificate" }, + { "xul", "application/vnd.mozilla.xul+xml" }, + { "cil", "application/vnd.ms-artgalry" }, + { "cab", "application/vnd.ms-cab-compressed" }, + { "xls", "application/vnd.ms-excel" }, + { "xlm", "application/vnd.ms-excel" }, + { "xla", "application/vnd.ms-excel" }, + { "xlc", "application/vnd.ms-excel" }, + { "xlt", "application/vnd.ms-excel" }, + { "xlw", "application/vnd.ms-excel" }, + { "xlam", "application/vnd.ms-excel.addin.macroenabled.12" }, + { "xlsb", "application/vnd.ms-excel.sheet.binary.macroenabled.12" }, + { "xlsm", "application/vnd.ms-excel.sheet.macroenabled.12" }, + { "xltm", "application/vnd.ms-excel.template.macroenabled.12" }, + { "eot", "application/vnd.ms-fontobject" }, + { "chm", "application/vnd.ms-htmlhelp" }, + { "ims", "application/vnd.ms-ims" }, + { "lrm", "application/vnd.ms-lrm" }, + { "thmx", "application/vnd.ms-officetheme" }, + { "cat", "application/vnd.ms-pki.seccat" }, + { "stl", "application/vnd.ms-pki.stl" }, + { "ppt", "application/vnd.ms-powerpoint" }, + { "pps", "application/vnd.ms-powerpoint" }, + { "pot", "application/vnd.ms-powerpoint" }, + { "ppam", "application/vnd.ms-powerpoint.addin.macroenabled.12" }, + { "pptm", "application/vnd.ms-powerpoint.presentation.macroenabled.12" }, + { "sldm", "application/vnd.ms-powerpoint.slide.macroenabled.12" }, + { "ppsm", "application/vnd.ms-powerpoint.slideshow.macroenabled.12" }, + { "potm", "application/vnd.ms-powerpoint.template.macroenabled.12" }, + { "mpp", "application/vnd.ms-project" }, + { "mpt", "application/vnd.ms-project" }, + { "docm", "application/vnd.ms-word.document.macroenabled.12" }, + { "dotm", "application/vnd.ms-word.template.macroenabled.12" }, + { "wps", "application/vnd.ms-works" }, + { "wks", "application/vnd.ms-works" }, + { "wcm", "application/vnd.ms-works" }, + { "wdb", "application/vnd.ms-works" }, + { "wpl", "application/vnd.ms-wpl" }, + { "xps", "application/vnd.ms-xpsdocument" }, + { "mseq", "application/vnd.mseq" }, + { "mus", "application/vnd.musician" }, + { "msty", "application/vnd.muvee.style" }, + { "taglet", "application/vnd.mynfc" }, + { "nlu", "application/vnd.neurolanguage.nlu" }, + { "ntf", "application/vnd.nitf" }, + { "nitf", "application/vnd.nitf" }, + { "nnd", "application/vnd.noblenet-directory" }, + { "nns", "application/vnd.noblenet-sealer" }, + { "nnw", "application/vnd.noblenet-web" }, + { "ngdat", "application/vnd.nokia.n-gage.data" }, + { "n-gage", "application/vnd.nokia.n-gage.symbian.install" }, + { "rpst", "application/vnd.nokia.radio-preset" }, + { "rpss", "application/vnd.nokia.radio-presets" }, + { "edm", "application/vnd.novadigm.edm" }, + { "edx", "application/vnd.novadigm.edx" }, + { "ext", "application/vnd.novadigm.ext" }, + { "odc", "application/vnd.oasis.opendocument.chart" }, + { "otc", "application/vnd.oasis.opendocument.chart-template" }, + { "odb", "application/vnd.oasis.opendocument.database" }, + { "odf", "application/vnd.oasis.opendocument.formula" }, + { "odft", "application/vnd.oasis.opendocument.formula-template" }, + { "odg", "application/vnd.oasis.opendocument.graphics" }, + { "otg", "application/vnd.oasis.opendocument.graphics-template" }, + { "odi", "application/vnd.oasis.opendocument.image" }, + { "oti", "application/vnd.oasis.opendocument.image-template" }, + { "odp", "application/vnd.oasis.opendocument.presentation" }, + { "otp", "application/vnd.oasis.opendocument.presentation-template" }, + { "ods", "application/vnd.oasis.opendocument.spreadsheet" }, + { "ots", "application/vnd.oasis.opendocument.spreadsheet-template" }, + { "odt", "application/vnd.oasis.opendocument.text" }, + { "odm", "application/vnd.oasis.opendocument.text-master" }, + { "ott", "application/vnd.oasis.opendocument.text-template" }, + { "oth", "application/vnd.oasis.opendocument.text-web" }, + { "xo", "application/vnd.olpc-sugar" }, + { "dd2", "application/vnd.oma.dd2+xml" }, + { "oxt", "application/vnd.openofficeorg.extension" }, + { "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" }, + { "sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide" }, + { "ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow" }, + { "potx", "application/vnd.openxmlformats-officedocument.presentationml.template" }, + { "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }, + { "xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template" }, + { "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }, + { "dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template" }, + { "mgp", "application/vnd.osgeo.mapguide.package" }, + { "dp", "application/vnd.osgi.dp" }, + { "esa", "application/vnd.osgi.subsystem" }, + { "pdb", "application/vnd.palm" }, + { "pqa", "application/vnd.palm" }, + { "oprc", "application/vnd.palm" }, + { "paw", "application/vnd.pawaafile" }, + { "str", "application/vnd.pg.format" }, + { "ei6", "application/vnd.pg.osasli" }, + { "efif", "application/vnd.picsel" }, + { "wg", "application/vnd.pmi.widget" }, + { "plf", "application/vnd.pocketlearn" }, + { "pbd", "application/vnd.powerbuilder6" }, + { "box", "application/vnd.previewsystems.box" }, + { "mgz", "application/vnd.proteus.magazine" }, + { "qps", "application/vnd.publishare-delta-tree" }, + { "ptid", "application/vnd.pvi.ptid1" }, + { "qxd", "application/vnd.quark.quarkxpress" }, + { "qxt", "application/vnd.quark.quarkxpress" }, + { "qwd", "application/vnd.quark.quarkxpress" }, + { "qwt", "application/vnd.quark.quarkxpress" }, + { "qxl", "application/vnd.quark.quarkxpress" }, + { "qxb", "application/vnd.quark.quarkxpress" }, + { "bed", "application/vnd.realvnc.bed" }, + { "mxl", "application/vnd.recordare.musicxml" }, + { "musicxml", "application/vnd.recordare.musicxml+xml" }, + { "cryptonote", "application/vnd.rig.cryptonote" }, + { "cod", "application/vnd.rim.cod" }, + { "rm", "application/vnd.rn-realmedia" }, + { "rmvb", "application/vnd.rn-realmedia-vbr" }, + { "link66", "application/vnd.route66.link66+xml" }, + { "st", "application/vnd.sailingtracker.track" }, + { "see", "application/vnd.seemail" }, + { "sema", "application/vnd.sema" }, + { "semd", "application/vnd.semd" }, + { "semf", "application/vnd.semf" }, + { "ifm", "application/vnd.shana.informed.formdata" }, + { "itp", "application/vnd.shana.informed.formtemplate" }, + { "iif", "application/vnd.shana.informed.interchange" }, + { "ipk", "application/vnd.shana.informed.package" }, + { "twd", "application/vnd.simtech-mindmapper" }, + { "twds", "application/vnd.simtech-mindmapper" }, + { "mmf", "application/vnd.smaf" }, + { "teacher", "application/vnd.smart.teacher" }, + { "sdkm", "application/vnd.solent.sdkm+xml" }, + { "sdkd", "application/vnd.solent.sdkm+xml" }, + { "dxp", "application/vnd.spotfire.dxp" }, + { "sfs", "application/vnd.spotfire.sfs" }, + { "sdc", "application/vnd.stardivision.calc" }, + { "sda", "application/vnd.stardivision.draw" }, + { "sdd", "application/vnd.stardivision.impress" }, + { "smf", "application/vnd.stardivision.math" }, + { "sdw", "application/vnd.stardivision.writer" }, + { "vor", "application/vnd.stardivision.writer" }, + { "sgl", "application/vnd.stardivision.writer-global" }, + { "smzip", "application/vnd.stepmania.package" }, + { "sm", "application/vnd.stepmania.stepchart" }, + { "sxc", "application/vnd.sun.xml.calc" }, + { "stc", "application/vnd.sun.xml.calc.template" }, + { "sxd", "application/vnd.sun.xml.draw" }, + { "std", "application/vnd.sun.xml.draw.template" }, + { "sxi", "application/vnd.sun.xml.impress" }, + { "sti", "application/vnd.sun.xml.impress.template" }, + { "sxm", "application/vnd.sun.xml.math" }, + { "sxw", "application/vnd.sun.xml.writer" }, + { "sxg", "application/vnd.sun.xml.writer.global" }, + { "stw", "application/vnd.sun.xml.writer.template" }, + { "sus", "application/vnd.sus-calendar" }, + { "susp", "application/vnd.sus-calendar" }, + { "svd", "application/vnd.svd" }, + { "sis", "application/vnd.symbian.install" }, + { "sisx", "application/vnd.symbian.install" }, + { "xsm", "application/vnd.syncml+xml" }, + { "bdm", "application/vnd.syncml.dm+wbxml" }, + { "xdm", "application/vnd.syncml.dm+xml" }, + { "tao", "application/vnd.tao.intent-module-archive" }, + { "pcap", "application/vnd.tcpdump.pcap" }, + { "cap", "application/vnd.tcpdump.pcap" }, + { "dmp", "application/vnd.tcpdump.pcap" }, + { "tmo", "application/vnd.tmobile-livetv" }, + { "tpt", "application/vnd.trid.tpt" }, + { "mxs", "application/vnd.triscape.mxs" }, + { "tra", "application/vnd.trueapp" }, + { "ufd", "application/vnd.ufdl" }, + { "ufdl", "application/vnd.ufdl" }, + { "utz", "application/vnd.uiq.theme" }, + { "umj", "application/vnd.umajin" }, + { "unityweb", "application/vnd.unity" }, + { "uoml", "application/vnd.uoml+xml" }, + { "vcx", "application/vnd.vcx" }, + { "vsd", "application/vnd.visio" }, + { "vst", "application/vnd.visio" }, + { "vss", "application/vnd.visio" }, + { "vsw", "application/vnd.visio" }, + { "vis", "application/vnd.visionary" }, + { "vsf", "application/vnd.vsf" }, + { "wbxml", "application/vnd.wap.wbxml" }, + { "wmlc", "application/vnd.wap.wmlc" }, + { "wmlsc", "application/vnd.wap.wmlscriptc" }, + { "wtb", "application/vnd.webturbo" }, + { "nbp", "application/vnd.wolfram.player" }, + { "wpd", "application/vnd.wordperfect" }, + { "wqd", "application/vnd.wqd" }, + { "stf", "application/vnd.wt.stf" }, + { "xar", "application/vnd.xara" }, + { "xfdl", "application/vnd.xfdl" }, + { "hvd", "application/vnd.yamaha.hv-dic" }, + { "hvs", "application/vnd.yamaha.hv-script" }, + { "hvp", "application/vnd.yamaha.hv-voice" }, + { "osf", "application/vnd.yamaha.openscoreformat" }, + { "osfpvg", "application/vnd.yamaha.openscoreformat.osfpvg+xml" }, + { "saf", "application/vnd.yamaha.smaf-audio" }, + { "spf", "application/vnd.yamaha.smaf-phrase" }, + { "cmp", "application/vnd.yellowriver-custom-menu" }, + { "zir", "application/vnd.zul" }, + { "zirz", "application/vnd.zul" }, + { "zaz", "application/vnd.zzazz.deck+xml" }, + { "vxml", "application/voicexml+xml" }, + { "wgt", "application/widget" }, + { "hlp", "application/winhlp" }, + { "wsdl", "application/wsdl+xml" }, + { "wspolicy", "application/wspolicy+xml" }, + { "7z", "application/x-7z-compressed" }, + { "abw", "application/x-abiword" }, + { "ace", "application/x-ace-compressed" }, + { "dmg", "application/x-apple-diskimage" }, + { "aab", "application/x-authorware-bin" }, + { "x32", "application/x-authorware-bin" }, + { "u32", "application/x-authorware-bin" }, + { "vox", "application/x-authorware-bin" }, + { "aam", "application/x-authorware-map" }, + { "aas", "application/x-authorware-seg" }, + { "bcpio", "application/x-bcpio" }, + { "torrent", "application/x-bittorrent" }, + { "blb", "application/x-blorb" }, + { "blorb", "application/x-blorb" }, + { "bz", "application/x-bzip" }, + { "bz2", "application/x-bzip2" }, + { "boz", "application/x-bzip2" }, + { "cbr", "application/x-cbr" }, + { "cba", "application/x-cbr" }, + { "cbt", "application/x-cbr" }, + { "cbz", "application/x-cbr" }, + { "cb7", "application/x-cbr" }, + { "vcd", "application/x-cdlink" }, + { "cfs", "application/x-cfs-compressed" }, + { "chat", "application/x-chat" }, + { "pgn", "application/x-chess-pgn" }, + { "nsc", "application/x-conference" }, + { "cpio", "application/x-cpio" }, + { "csh", "application/x-csh" }, + { "deb", "application/x-debian-package" }, + { "udeb", "application/x-debian-package" }, + { "dgc", "application/x-dgc-compressed" }, + { "dir", "application/x-director" }, + { "dcr", "application/x-director" }, + { "dxr", "application/x-director" }, + { "cst", "application/x-director" }, + { "cct", "application/x-director" }, + { "cxt", "application/x-director" }, + { "w3d", "application/x-director" }, + { "fgd", "application/x-director" }, + { "swa", "application/x-director" }, + { "wad", "application/x-doom" }, + { "ncx", "application/x-dtbncx+xml" }, + { "dtb", "application/x-dtbook+xml" }, + { "res", "application/x-dtbresource+xml" }, + { "dvi", "application/x-dvi" }, + { "evy", "application/x-envoy" }, + { "eva", "application/x-eva" }, + { "bdf", "application/x-font-bdf" }, + { "gsf", "application/x-font-ghostscript" }, + { "psf", "application/x-font-linux-psf" }, + { "otf", "application/x-font-otf" }, + { "pcf", "application/x-font-pcf" }, + { "snf", "application/x-font-snf" }, + { "ttf", "application/x-font-ttf" }, + { "ttc", "application/x-font-ttf" }, + { "pfa", "application/x-font-type1" }, + { "pfb", "application/x-font-type1" }, + { "pfm", "application/x-font-type1" }, + { "afm", "application/x-font-type1" }, + { "woff", "application/font-woff" }, + { "arc", "application/x-freearc" }, + { "spl", "application/x-futuresplash" }, + { "gca", "application/x-gca-compressed" }, + { "ulx", "application/x-glulx" }, + { "gnumeric", "application/x-gnumeric" }, + { "gramps", "application/x-gramps-xml" }, + { "gtar", "application/x-gtar" }, + { "hdf", "application/x-hdf" }, + { "install", "application/x-install-instructions" }, + { "iso", "application/x-iso9660-image" }, + { "jnlp", "application/x-java-jnlp-file" }, + { "latex", "application/x-latex" }, + { "lzh", "application/x-lzh-compressed" }, + { "lha", "application/x-lzh-compressed" }, + { "mie", "application/x-mie" }, + { "prc", "application/x-mobipocket-ebook" }, + { "mobi", "application/x-mobipocket-ebook" }, + { "application", "application/x-ms-application" }, + { "lnk", "application/x-ms-shortcut" }, + { "wmd", "application/x-ms-wmd" }, + { "wmz", "application/x-msmetafile" }, + { "xbap", "application/x-ms-xbap" }, + { "mdb", "application/x-msaccess" }, + { "obd", "application/x-msbinder" }, + { "crd", "application/x-mscardfile" }, + { "clp", "application/x-msclip" }, + { "exe", "application/x-msdownload" }, + { "dll", "application/x-msdownload" }, + { "com", "application/x-msdownload" }, + { "bat", "application/x-msdownload" }, + { "msi", "application/x-msdownload" }, + { "mvb", "application/x-msmediaview" }, + { "m13", "application/x-msmediaview" }, + { "m14", "application/x-msmediaview" }, + { "wmf", "application/x-msmetafile" }, + { "emf", "application/x-msmetafile" }, + { "emz", "application/x-msmetafile" }, + { "mny", "application/x-msmoney" }, + { "pub", "application/x-mspublisher" }, + { "scd", "application/x-msschedule" }, + { "trm", "application/x-msterminal" }, + { "wri", "application/x-mswrite" }, + { "nc", "application/x-netcdf" }, + { "cdf", "application/x-netcdf" }, + { "nzb", "application/x-nzb" }, + { "p12", "application/x-pkcs12" }, + { "pfx", "application/x-pkcs12" }, + { "p7b", "application/x-pkcs7-certificates" }, + { "spc", "application/x-pkcs7-certificates" }, + { "p7r", "application/x-pkcs7-certreqresp" }, + { "rar", "application/x-rar-compressed" }, + { "ris", "application/x-research-info-systems" }, + { "sh", "application/x-sh" }, + { "shar", "application/x-shar" }, + { "swf", "application/x-shockwave-flash" }, + { "xap", "application/x-silverlight-app" }, + { "sql", "application/x-sql" }, + { "sit", "application/x-stuffit" }, + { "sitx", "application/x-stuffitx" }, + { "srt", "application/x-subrip" }, + { "sv4cpio", "application/x-sv4cpio" }, + { "sv4crc", "application/x-sv4crc" }, + { "t3", "application/x-t3vm-image" }, + { "gam", "application/x-tads" }, + { "tar", "application/x-tar" }, + { "tcl", "application/x-tcl" }, + { "tex", "application/x-tex" }, + { "tfm", "application/x-tex-tfm" }, + { "texinfo", "application/x-texinfo" }, + { "texi", "application/x-texinfo" }, + { "obj", "application/x-tgif" }, + { "ustar", "application/x-ustar" }, + { "src", "application/x-wais-source" }, + { "der", "application/x-x509-ca-cert" }, + { "crt", "application/x-x509-ca-cert" }, + { "fig", "application/x-xfig" }, + { "xlf", "application/x-xliff+xml" }, + { "xpi", "application/x-xpinstall" }, + { "xz", "application/x-xz" }, + { "z1", "application/x-zmachine" }, + { "z2", "application/x-zmachine" }, + { "z3", "application/x-zmachine" }, + { "z4", "application/x-zmachine" }, + { "z5", "application/x-zmachine" }, + { "z6", "application/x-zmachine" }, + { "z7", "application/x-zmachine" }, + { "z8", "application/x-zmachine" }, + { "xaml", "application/xaml+xml" }, + { "xdf", "application/xcap-diff+xml" }, + { "xenc", "application/xenc+xml" }, + { "xhtml", "application/xhtml+xml" }, + { "xht", "application/xhtml+xml" }, + { "xml", "application/xml" }, + { "xsl", "application/xml" }, + { "dtd", "application/xml-dtd" }, + { "xop", "application/xop+xml" }, + { "xpl", "application/xproc+xml" }, + { "xslt", "application/xslt+xml" }, + { "xspf", "application/xspf+xml" }, + { "mxml", "application/xv+xml" }, + { "xhvml", "application/xv+xml" }, + { "xvml", "application/xv+xml" }, + { "xvm", "application/xv+xml" }, + { "yang", "application/yang" }, + { "yin", "application/yin+xml" }, + { "zip", "application/zip" }, + { "adp", "audio/adpcm" }, + { "au", "audio/basic" }, + { "snd", "audio/basic" }, + { "mid", "audio/midi" }, + { "midi", "audio/midi" }, + { "kar", "audio/midi" }, + { "rmi", "audio/midi" }, + { "mp4a", "audio/mp4" }, + { "mpga", "audio/mpeg" }, + { "mp2", "audio/mpeg" }, + { "mp2a", "audio/mpeg" }, + { "mp3", "audio/mpeg" }, + { "m2a", "audio/mpeg" }, + { "m3a", "audio/mpeg" }, + { "oga", "audio/ogg" }, + { "ogg", "audio/ogg" }, + { "spx", "audio/ogg" }, + { "s3m", "audio/s3m" }, + { "sil", "audio/silk" }, + { "uva", "audio/vnd.dece.audio" }, + { "uvva", "audio/vnd.dece.audio" }, + { "eol", "audio/vnd.digital-winds" }, + { "dra", "audio/vnd.dra" }, + { "dts", "audio/vnd.dts" }, + { "dtshd", "audio/vnd.dts.hd" }, + { "lvp", "audio/vnd.lucent.voice" }, + { "pya", "audio/vnd.ms-playready.media.pya" }, + { "ecelp4800", "audio/vnd.nuera.ecelp4800" }, + { "ecelp7470", "audio/vnd.nuera.ecelp7470" }, + { "ecelp9600", "audio/vnd.nuera.ecelp9600" }, + { "rip", "audio/vnd.rip" }, + { "weba", "audio/webm" }, + { "aac", "audio/x-aac" }, + { "aif", "audio/x-aiff" }, + { "aiff", "audio/x-aiff" }, + { "aifc", "audio/x-aiff" }, + { "caf", "audio/x-caf" }, + { "flac", "audio/x-flac" }, + { "mka", "audio/x-matroska" }, + { "m3u", "audio/x-mpegurl" }, + { "wax", "audio/x-ms-wax" }, + { "wma", "audio/x-ms-wma" }, + { "ram", "audio/x-pn-realaudio" }, + { "ra", "audio/x-pn-realaudio" }, + { "rmp", "audio/x-pn-realaudio-plugin" }, + { "wav", "audio/x-wav" }, + { "xm", "audio/xm" }, + { "cdx", "chemical/x-cdx" }, + { "cif", "chemical/x-cif" }, + { "cmdf", "chemical/x-cmdf" }, + { "cml", "chemical/x-cml" }, + { "csml", "chemical/x-csml" }, + { "xyz", "chemical/x-xyz" }, + { "bmp", "image/bmp" }, + { "cgm", "image/cgm" }, + { "g3", "image/g3fax" }, + { "gif", "image/gif" }, + { "ief", "image/ief" }, + { "jpeg", "image/jpeg" }, + { "jpg", "image/jpeg" }, + { "jpe", "image/jpeg" }, + { "ktx", "image/ktx" }, + { "png", "image/png" }, + { "btif", "image/prs.btif" }, + { "sgi", "image/sgi" }, + { "svg", "image/svg+xml" }, + { "svgz", "image/svg+xml" }, + { "tiff", "image/tiff" }, + { "tif", "image/tiff" }, + { "psd", "image/vnd.adobe.photoshop" }, + { "uvi", "image/vnd.dece.graphic" }, + { "uvvi", "image/vnd.dece.graphic" }, + { "uvg", "image/vnd.dece.graphic" }, + { "uvvg", "image/vnd.dece.graphic" }, + { "sub", "text/vnd.dvb.subtitle" }, + { "djvu", "image/vnd.djvu" }, + { "djv", "image/vnd.djvu" }, + { "dwg", "image/vnd.dwg" }, + { "dxf", "image/vnd.dxf" }, + { "fbs", "image/vnd.fastbidsheet" }, + { "fpx", "image/vnd.fpx" }, + { "fst", "image/vnd.fst" }, + { "mmr", "image/vnd.fujixerox.edmics-mmr" }, + { "rlc", "image/vnd.fujixerox.edmics-rlc" }, + { "mdi", "image/vnd.ms-modi" }, + { "wdp", "image/vnd.ms-photo" }, + { "npx", "image/vnd.net-fpx" }, + { "wbmp", "image/vnd.wap.wbmp" }, + { "xif", "image/vnd.xiff" }, + { "webp", "image/webp" }, + { "3ds", "image/x-3ds" }, + { "ras", "image/x-cmu-raster" }, + { "cmx", "image/x-cmx" }, + { "fh", "image/x-freehand" }, + { "fhc", "image/x-freehand" }, + { "fh4", "image/x-freehand" }, + { "fh5", "image/x-freehand" }, + { "fh7", "image/x-freehand" }, + { "ico", "image/x-icon" }, + { "sid", "image/x-mrsid-image" }, + { "pcx", "image/x-pcx" }, + { "pic", "image/x-pict" }, + { "pct", "image/x-pict" }, + { "pnm", "image/x-portable-anymap" }, + { "pbm", "image/x-portable-bitmap" }, + { "pgm", "image/x-portable-graymap" }, + { "ppm", "image/x-portable-pixmap" }, + { "rgb", "image/x-rgb" }, + { "tga", "image/x-tga" }, + { "xbm", "image/x-xbitmap" }, + { "xpm", "image/x-xpixmap" }, + { "xwd", "image/x-xwindowdump" }, + { "eml", "message/rfc822" }, + { "mime", "message/rfc822" }, + { "igs", "model/iges" }, + { "iges", "model/iges" }, + { "msh", "model/mesh" }, + { "mesh", "model/mesh" }, + { "silo", "model/mesh" }, + { "dae", "model/vnd.collada+xml" }, + { "dwf", "model/vnd.dwf" }, + { "gdl", "model/vnd.gdl" }, + { "gtw", "model/vnd.gtw" }, + { "mts", "model/vnd.mts" }, + { "vtu", "model/vnd.vtu" }, + { "wrl", "model/vrml" }, + { "vrml", "model/vrml" }, + { "x3db", "model/x3d+binary" }, + { "x3dbz", "model/x3d+binary" }, + { "x3dv", "model/x3d+vrml" }, + { "x3dvz", "model/x3d+vrml" }, + { "x3d", "model/x3d+xml" }, + { "x3dz", "model/x3d+xml" }, + { "appcache", "text/cache-manifest" }, + { "ics", "text/calendar" }, + { "ifb", "text/calendar" }, + { "css", "text/css" }, + { "csv", "text/csv" }, + { "html", "text/html" }, + { "htm", "text/html" }, + { "n3", "text/n3" }, + { "txt", "text/plain" }, + { "text", "text/plain" }, + { "conf", "text/plain" }, + { "def", "text/plain" }, + { "list", "text/plain" }, + { "log", "text/plain" }, + { "in", "text/plain" }, + { "dsc", "text/prs.lines.tag" }, + { "rtx", "text/richtext" }, + { "sgml", "text/sgml" }, + { "sgm", "text/sgml" }, + { "tsv", "text/tab-separated-values" }, + { "t", "text/troff" }, + { "tr", "text/troff" }, + { "roff", "text/troff" }, + { "man", "text/troff" }, + { "me", "text/troff" }, + { "ms", "text/troff" }, + { "ttl", "text/turtle" }, + { "uri", "text/uri-list" }, + { "uris", "text/uri-list" }, + { "urls", "text/uri-list" }, + { "vcard", "text/vcard" }, + { "curl", "text/vnd.curl" }, + { "dcurl", "text/vnd.curl.dcurl" }, + { "scurl", "text/vnd.curl.scurl" }, + { "mcurl", "text/vnd.curl.mcurl" }, + { "fly", "text/vnd.fly" }, + { "flx", "text/vnd.fmi.flexstor" }, + { "gv", "text/vnd.graphviz" }, + { "3dml", "text/vnd.in3d.3dml" }, + { "spot", "text/vnd.in3d.spot" }, + { "jad", "text/vnd.sun.j2me.app-descriptor" }, + { "wml", "text/vnd.wap.wml" }, + { "wmls", "text/vnd.wap.wmlscript" }, + { "s", "text/x-asm" }, + { "asm", "text/x-asm" }, + { "c", "text/x-c" }, + { "cc", "text/x-c" }, + { "cxx", "text/x-c" }, + { "cpp", "text/x-c" }, + { "h", "text/x-c" }, + { "hh", "text/x-c" }, + { "dic", "text/x-c" }, + { "f", "text/x-fortran" }, + { "for", "text/x-fortran" }, + { "f77", "text/x-fortran" }, + { "f90", "text/x-fortran" }, + { "java", "text/x-java-source" }, + { "opml", "text/x-opml" }, + { "p", "text/x-pascal" }, + { "pas", "text/x-pascal" }, + { "nfo", "text/x-nfo" }, + { "etx", "text/x-setext" }, + { "sfv", "text/x-sfv" }, + { "uu", "text/x-uuencode" }, + { "vcs", "text/x-vcalendar" }, + { "vcf", "text/x-vcard" }, + { "3gp", "video/3gpp" }, + { "3g2", "video/3gpp2" }, + { "h261", "video/h261" }, + { "h263", "video/h263" }, + { "h264", "video/h264" }, + { "jpgv", "video/jpeg" }, + { "jpm", "video/jpm" }, + { "jpgm", "video/jpm" }, + { "mj2", "video/mj2" }, + { "mjp2", "video/mj2" }, + { "mp4", "video/mp4" }, + { "mp4v", "video/mp4" }, + { "mpg4", "video/mp4" }, + { "mpeg", "video/mpeg" }, + { "mpg", "video/mpeg" }, + { "mpe", "video/mpeg" }, + { "m1v", "video/mpeg" }, + { "m2v", "video/mpeg" }, + { "ogv", "video/ogg" }, + { "qt", "video/quicktime" }, + { "mov", "video/quicktime" }, + { "uvh", "video/vnd.dece.hd" }, + { "uvvh", "video/vnd.dece.hd" }, + { "uvm", "video/vnd.dece.mobile" }, + { "uvvm", "video/vnd.dece.mobile" }, + { "uvp", "video/vnd.dece.pd" }, + { "uvvp", "video/vnd.dece.pd" }, + { "uvs", "video/vnd.dece.sd" }, + { "uvvs", "video/vnd.dece.sd" }, + { "uvv", "video/vnd.dece.video" }, + { "uvvv", "video/vnd.dece.video" }, + { "dvb", "video/vnd.dvb.file" }, + { "fvt", "video/vnd.fvt" }, + { "mxu", "video/vnd.mpegurl" }, + { "m4u", "video/vnd.mpegurl" }, + { "pyv", "video/vnd.ms-playready.media.pyv" }, + { "uvu", "video/vnd.uvvu.mp4" }, + { "uvvu", "video/vnd.uvvu.mp4" }, + { "viv", "video/vnd.vivo" }, + { "webm", "video/webm" }, + { "f4v", "video/x-f4v" }, + { "fli", "video/x-fli" }, + { "flv", "video/x-flv" }, + { "m4v", "video/x-m4v" }, + { "mkv", "video/x-matroska" }, + { "mk3d", "video/x-matroska" }, + { "mks", "video/x-matroska" }, + { "mng", "video/x-mng" }, + { "asf", "video/x-ms-asf" }, + { "asx", "video/x-ms-asf" }, + { "vob", "video/x-ms-vob" }, + { "wm", "video/x-ms-wm" }, + { "wmv", "video/x-ms-wmv" }, + { "wmx", "video/x-ms-wmx" }, + { "wvx", "video/x-ms-wvx" }, + { "avi", "video/x-msvideo" }, + { "movie", "video/x-sgi-movie" }, + { "smv", "video/x-smv" }, + { "ice", "x-conference/x-cooltalk" }, + { NULL, NULL } +}; + +#endif /* PHP_CLI_SERVER_MIME_TYPE_MAP_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/sapi/cli/php.1.in b/sapi/cli/php.1.in index 8672b3ba33..4d536df53c 100644 --- a/sapi/cli/php.1.in +++ b/sapi/cli/php.1.in @@ -1,4 +1,4 @@ -.TH PHP 1 "2013" "The PHP Group" "Scripting Language" +.TH PHP 1 "2014" "The PHP Group" "Scripting Language" .SH NAME php \- PHP Command Line Interface 'CLI' .P @@ -454,7 +454,7 @@ contributors all around the world. .SH VERSION INFORMATION This manpage describes \fBphp\fP, version @PHP_VERSION@. .SH COPYRIGHT -Copyright \(co 1997\-2013 The PHP Group +Copyright \(co 1997\-2014 The PHP Group .LP 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 diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index e9bc9dcdc0..60b331f386 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -104,6 +104,7 @@ #include "php_http_parser.h" #include "php_cli_server.h" +#include "mime_type_map.h" #include "php_cli_process_title.h" @@ -194,6 +195,7 @@ typedef struct php_cli_server { size_t router_len; socklen_t socklen; HashTable clients; + HashTable extension_mime_types; } php_cli_server; typedef struct php_cli_server_http_response_status_code_pair { @@ -201,11 +203,6 @@ typedef struct php_cli_server_http_response_status_code_pair { const char *str; } php_cli_server_http_response_status_code_pair; -typedef struct php_cli_server_ext_mime_type_pair { - const char *ext; - const char *mime_type; -} php_cli_server_ext_mime_type_pair; - static php_cli_server_http_response_status_code_pair status_map[] = { { 100, "Continue" }, { 101, "Switching Protocols" }, @@ -223,6 +220,7 @@ static php_cli_server_http_response_status_code_pair status_map[] = { { 304, "Not Modified" }, { 305, "Use Proxy" }, { 307, "Temporary Redirect" }, + { 308, "Permanent Redirect" }, { 400, "Bad Request" }, { 401, "Unauthorized" }, { 402, "Payment Required" }, @@ -241,6 +239,7 @@ static php_cli_server_http_response_status_code_pair status_map[] = { { 415, "Unsupported Media Type" }, { 416, "Requested Range Not Satisfiable" }, { 417, "Expectation Failed" }, + { 426, "Upgrade Required" }, { 428, "Precondition Required" }, { 429, "Too Many Requests" }, { 431, "Request Header Fields Too Large" }, @@ -260,64 +259,6 @@ static php_cli_server_http_response_status_code_pair template_map[] = { { 501, "<h1>%s</h1><p>Request method not supported.</p>" } }; -static php_cli_server_ext_mime_type_pair mime_type_map[] = { - { "html", "text/html" }, - { "htm", "text/html" }, - { "js", "text/javascript" }, - { "css", "text/css" }, - { "gif", "image/gif" }, - { "jpg", "image/jpeg" }, - { "jpeg", "image/jpeg" }, - { "jpe", "image/jpeg" }, - { "pdf", "application/pdf" }, - { "png", "image/png" }, - { "svg", "image/svg+xml" }, - { "txt", "text/plain" }, - { "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" }, - { "xml", "application/xml" }, - { "xsl", "application/xml" }, - { "xsd", "application/xml" }, - { NULL, NULL } -}; - static int php_cli_output_is_tty = OUTPUT_NOT_CHECKED; static size_t php_cli_server_client_send_through(php_cli_server_client *client, const char *str, size_t str_len); @@ -463,15 +404,14 @@ static void append_essential_headers(smart_str* buffer, php_cli_server_client *c smart_str_appendl_ex(buffer, "Connection: close\r\n", sizeof("Connection: close\r\n") - 1, persistent); } /* }}} */ -static const char *get_mime_type(const char *ext, size_t ext_len) /* {{{ */ +static const char *get_mime_type(const php_cli_server *server, const char *ext, size_t ext_len) /* {{{ */ { - php_cli_server_ext_mime_type_pair *pair; - for (pair = mime_type_map; pair->ext; pair++) { - size_t len = strlen(pair->ext); - if (len == ext_len && memcmp(pair->ext, ext, len) == 0) { - return pair->mime_type; - } + char *mime_type = NULL; + + if (zend_hash_find(&server->extension_mime_types, ext, ext_len + 1, (void **) &mime_type) == SUCCESS) { + return mime_type; } + return NULL; } /* }}} */ @@ -893,13 +833,11 @@ static void php_cli_server_poller_remove(php_cli_server_poller *poller, int mode #endif } /* }}} */ -static int php_cli_server_poller_poll(php_cli_server_poller *poller, const struct timeval *tv) /* {{{ */ +static int php_cli_server_poller_poll(php_cli_server_poller *poller, 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, &t); + return php_select(poller->max_fd + 1, &poller->active.rfds, &poller->active.wfds, NULL, tv); } /* }}} */ static int php_cli_server_poller_iter_on_active(php_cli_server_poller *poller, void *opaque, int(*callback)(void *, int fd, int events)) /* {{{ */ @@ -2044,7 +1982,7 @@ static int php_cli_server_begin_send_static(php_cli_server *server, php_cli_serv { php_cli_server_chunk *chunk; smart_str buffer = { 0 }; - const char *mime_type = get_mime_type(client->request.ext, client->request.ext_len); + const char *mime_type = get_mime_type(server, client->request.ext, client->request.ext_len); if (!mime_type) { mime_type = "application/octet-stream"; } @@ -2204,9 +2142,30 @@ static int php_cli_server_dispatch(php_cli_server *server, php_cli_server_client } /* }}} */ +static int php_cli_server_mime_type_ctor(php_cli_server *server, const php_cli_server_ext_mime_type_pair *mime_type_map) /* {{{ */ +{ + const php_cli_server_ext_mime_type_pair *pair; + + if (zend_hash_init(&server->extension_mime_types, 0, NULL, NULL, 1) != SUCCESS) { + return FAILURE; + } + + for (pair = mime_type_map; pair->ext; pair++) { + size_t ext_len = 0, mime_type_len = 0; + + ext_len = strlen(pair->ext); + mime_type_len = strlen(pair->mime_type); + + zend_hash_add(&server->extension_mime_types, pair->ext, ext_len + 1, (void *) pair->mime_type, mime_type_len + 1, NULL); + } + + return SUCCESS; +} /* }}} */ + static void php_cli_server_dtor(php_cli_server *server TSRMLS_DC) /* {{{ */ { zend_hash_destroy(&server->clients); + zend_hash_destroy(&server->extension_mime_types); if (server->server_sock >= 0) { closesocket(server->server_sock); } @@ -2324,6 +2283,11 @@ static int php_cli_server_ctor(php_cli_server *server, const char *addr, const c server->router_len = 0; } + if (php_cli_server_mime_type_ctor(server, mime_type_map) == FAILURE) { + retval = FAILURE; + goto out; + } + server->is_running = 1; out: if (retval != SUCCESS) { @@ -2475,7 +2439,7 @@ static int php_cli_server_do_event_loop(php_cli_server *server TSRMLS_DC) /* {{{ { int retval = SUCCESS; while (server->is_running) { - static const struct timeval tv = { 1, 0 }; + struct timeval tv = { 1, 0 }; int n = php_cli_server_poller_poll(&server->poller, &tv); if (n > 0) { php_cli_server_do_event_for_each_fd(server, diff --git a/sapi/cli/tests/bug61977.phpt b/sapi/cli/tests/bug61977.phpt index 09a6ba6d23..6250c9aec0 100644 --- a/sapi/cli/tests/bug61977.phpt +++ b/sapi/cli/tests/bug61977.phpt @@ -48,7 +48,7 @@ foo.html => Content-Type: text/html; charset=UTF-8 foo.htm => Content-Type: text/html; charset=UTF-8 foo.svg => Content-Type: image/svg+xml foo.css => Content-Type: text/css; charset=UTF-8 -foo.js => Content-Type: text/javascript; charset=UTF-8 +foo.js => Content-Type: application/javascript foo.png => Content-Type: image/png foo.webm => Content-Type: video/webm foo.ogv => Content-Type: video/ogg diff --git a/sapi/cli/tests/bug67429.phpt b/sapi/cli/tests/bug67429.phpt new file mode 100644 index 0000000000..856946b29d --- /dev/null +++ b/sapi/cli/tests/bug67429.phpt @@ -0,0 +1,49 @@ +--TEST-- +FR #67429 (CLI server is missing some new HTTP response codes) +--SKIPIF-- +<?php +include "skipif.inc"; +?> +--FILE-- +<?php +include "php_cli_server.inc"; + +foreach ([308, 426] as $code) { + php_cli_server_start(<<<PHP +http_response_code($code); +PHP + ); + + list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS); + $port = intval($port)?:80; + + $fp = fsockopen($host, $port, $errno, $errstr, 0.5); + if (!$fp) { + die("connect failed"); + } + + if(fwrite($fp, <<<HEADER +GET / HTTP/1.1 + + +HEADER + )) { + while (!feof($fp)) { + echo fgets($fp); + } + } + + fclose($fp); +} +?> +--EXPECTF-- +HTTP/1.1 308 Permanent Redirect +Connection: close +X-Powered-By: %s +Content-type: text/html; charset=UTF-8 + +HTTP/1.1 426 Upgrade Required +Connection: close +X-Powered-By: %s +Content-type: text/html; charset=UTF-8 + diff --git a/sapi/continuity/capi.c b/sapi/continuity/capi.c index 87fd9328f2..30d10ed0a0 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-2013 The PHP Group. All rights reserved."); + logFmsg(0, "mod/php: Copyright (c) 1999-2014 The PHP Group. All rights reserved."); sapi_startup(&capi_sapi_module); capi_sapi_module.startup(&capi_sapi_module); diff --git a/sapi/fpm/fpm/events/epoll.c b/sapi/fpm/fpm/events/epoll.c index 2857ea2a09..b55cb44b15 100644 --- a/sapi/fpm/fpm/events/epoll.c +++ b/sapi/fpm/fpm/events/epoll.c @@ -46,7 +46,7 @@ static struct fpm_event_module_s epoll_module = { static struct epoll_event *epollfds = NULL; static int nepollfds = 0; -static int epollfd = 0; +static int epollfd = -1; #endif /* HAVE_EPOLL */ @@ -103,6 +103,10 @@ static int fpm_event_epoll_clean() /* {{{ */ free(epollfds); epollfds = NULL; } + if (epollfd != -1) { + close(epollfd); + epollfd = -1; + } nepollfds = 0; diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index ae7908642c..34e0480101 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -1075,6 +1075,9 @@ static int fpm_conf_process_all_pools() /* {{{ */ } } for (kv = wp->config->php_admin_values; kv; kv = kv->next) { + if (!strcasecmp(kv->key, "error_log") && !strcasecmp(kv->value, "syslog")) { + continue; + } for (p = options; *p; p++) { if (!strcasecmp(kv->key, *p)) { fpm_evaluate_full_path(&kv->value, wp, NULL, 0); diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 807ea8bb5d..09371314d2 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1148,19 +1148,6 @@ static void init_request_info(TSRMLS_D) TRANSLATE_SLASHES(env_document_root); } - if (env_path_translated != NULL && env_redirect_url != NULL && - env_path_translated != script_path_translated && - strcmp(env_path_translated, script_path_translated) != 0) { - /* - * pretty much apache specific. If we have a redirect_url - * then our script_filename and script_name point to the - * php executable - */ - script_path_translated = env_path_translated; - /* we correct SCRIPT_NAME now in case we don't have PATH_INFO */ - env_script_name = env_redirect_url; - } - #ifdef __riscos__ /* Convert path to unix format*/ __riscosify_control |= __RISCOSIFY_DONT_CHECK_DIR; @@ -1329,7 +1316,7 @@ static void init_request_info(TSRMLS_D) efree(pt); } } else { - /* make sure path_info/translated are empty */ + /* make sure original values are remembered in ORIG_ copies if we've changed them */ if (!orig_script_filename || (script_path_translated != orig_script_filename && strcmp(script_path_translated, orig_script_filename) != 0)) { @@ -1338,16 +1325,6 @@ static void init_request_info(TSRMLS_D) } script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME", script_path_translated TSRMLS_CC); } - if (env_redirect_url) { - if (orig_path_info) { - _sapi_cgibin_putenv("ORIG_PATH_INFO", orig_path_info TSRMLS_CC); - _sapi_cgibin_putenv("PATH_INFO", NULL TSRMLS_CC); - } - if (orig_path_translated) { - _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC); - _sapi_cgibin_putenv("PATH_TRANSLATED", NULL TSRMLS_CC); - } - } if (env_script_name != orig_script_name) { if (orig_script_name) { _sapi_cgibin_putenv("ORIG_SCRIPT_NAME", orig_script_name TSRMLS_CC); diff --git a/sapi/fpm/fpm/fpm_unix.c b/sapi/fpm/fpm/fpm_unix.c index b32213fa74..68978ee75d 100644 --- a/sapi/fpm/fpm/fpm_unix.c +++ b/sapi/fpm/fpm/fpm_unix.c @@ -39,7 +39,7 @@ int fpm_unix_resolve_socket_premissions(struct fpm_worker_pool_s *wp) /* {{{ */ /* uninitialized */ wp->socket_uid = -1; wp->socket_gid = -1; - wp->socket_mode = 0666; + wp->socket_mode = 0660; if (!c) { return 0; diff --git a/sapi/fpm/php-fpm.conf.in b/sapi/fpm/php-fpm.conf.in index acdff31f17..c5f4abc59c 100644 --- a/sapi/fpm/php-fpm.conf.in +++ b/sapi/fpm/php-fpm.conf.in @@ -166,10 +166,10 @@ listen = 127.0.0.1:9000 ; permissions must be set in order to allow connections from a web server. Many ; BSD-derived systems allow connections regardless of permissions. ; Default Values: user and group are set as the running user -; mode is set to 0666 +; mode is set to 0660 ;listen.owner = @php_fpm_user@ ;listen.group = @php_fpm_group@ -;listen.mode = 0666 +;listen.mode = 0660 ; List of ipv4 addresses of FastCGI clients which are allowed to connect. ; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index 850433d29c..63051c1645 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -615,7 +615,7 @@ static void cli_usage( TSRMLS_D ) " args... Arguments passed to script.\n"; php_output_startup(); php_output_activate(TSRMLS_C); - php_printf( usage ); + php_printf( "%s", usage ); #ifdef PHP_OUTPUT_NEWAPI php_output_end_all(TSRMLS_C); #else diff --git a/sapi/phpdbg/.gitignore b/sapi/phpdbg/.gitignore index 297efcbc42..51165dab2f 100644 --- a/sapi/phpdbg/.gitignore +++ b/sapi/phpdbg/.gitignore @@ -1,5 +1,6 @@ .libs/ -./phpdbg +phpdbg *.lo *.o +*.output build diff --git a/sapi/phpdbg/.travis.yml b/sapi/phpdbg/.travis.yml index 353402858e..d5b492e7cf 100644 --- a/sapi/phpdbg/.travis.yml +++ b/sapi/phpdbg/.travis.yml @@ -1,3 +1,12 @@ language: c -script: ./travis/ci.sh +env: +- PHP="PHP-5.4" +- PHP="PHP-5.5" +- PHP="PHP-5.6" +- PHP="master" + +before_script: ./travis/ci.sh + +script: +- ./php-src/sapi/cli/php php-src/sapi/phpdbg/tests/run-tests.php -diff2stdout --phpdbg php-src/sapi/phpdbg/phpdbg diff --git a/sapi/phpdbg/Makefile.frag b/sapi/phpdbg/Makefile.frag index 5be6d5b00f..36c7512d69 100644 --- a/sapi/phpdbg/Makefile.frag +++ b/sapi/phpdbg/Makefile.frag @@ -8,12 +8,27 @@ $(BUILD_SHARED): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_PHPDBG_OBJS) $(BUILD_BINARY): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_PHPDBG_OBJS) $(BUILD_PHPDBG) +%.c: %.y +%.c: %.l + +$(builddir)/phpdbg_lexer.lo: $(srcdir)/phpdbg_parser.h + +$(srcdir)/phpdbg_lexer.c: $(srcdir)/phpdbg_lexer.l + @(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date -cbdFo $(srcdir)/phpdbg_lexer.c $(srcdir)/phpdbg_lexer.l) + +$(srcdir)/phpdbg_parser.h: $(srcdir)/phpdbg_parser.c +$(srcdir)/phpdbg_parser.c: $(srcdir)/phpdbg_parser.y + @$(YACC) -p phpdbg_ -v -d $(srcdir)/phpdbg_parser.y -o $@ + 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) + @echo "Installing phpdbg man page: $(INSTALL_ROOT)$(mandir)/man1/" + @$(mkinstalldirs) $(INSTALL_ROOT)$(mandir)/man1 + @$(INSTALL_DATA) $(srcdir)/phpdbg.1 $(INSTALL_ROOT)$(mandir)/man1/$(program_prefix)phpdbg$(program_suffix).1 clean-phpdbg: @echo "Cleaning phpdbg object files ..." @@ -25,4 +40,3 @@ test-phpdbg: .PHONY: clean-phpdbg test-phpdbg - diff --git a/sapi/phpdbg/config.m4 b/sapi/phpdbg/config.m4 index 274e6409d0..d78a439af0 100644 --- a/sapi/phpdbg/config.m4 +++ b/sapi/phpdbg/config.m4 @@ -3,12 +3,13 @@ dnl $Id$ dnl PHP_ARG_ENABLE(phpdbg, for phpdbg support, -[ --enable-phpdbg Build phpdbg], yes, yes) +[ --enable-phpdbg Build phpdbg], no, no) PHP_ARG_ENABLE(phpdbg-debug, for phpdbg debug build, -[ --enable-phpdbg-debug Build phpdbg in debug mode], no, no) +[ --enable-phpdbg-debug Build phpdbg in debug mode], no, no) if test "$PHP_PHPDBG" != "no"; then + AC_HEADER_TIOCGWINSZ AC_DEFINE(HAVE_PHPDBG, 1, [ ]) if test "$PHP_PHPDBG_DEBUG" != "no"; then @@ -18,17 +19,22 @@ if test "$PHP_PHPDBG" != "no"; then 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_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.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 phpdbg_watch.c phpdbg_btree.c" + if test "$PHP_READLINE" != "no" -o "$PHP_LIBEDIT" != "no"; then + PHPDBG_EXTRA_LIBS="$PHP_READLINE_LIBS" + fi + PHP_SUBST(PHP_PHPDBG_CFLAGS) PHP_SUBST(PHP_PHPDBG_FILES) - - PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/phpdbg/Makefile.frag]) + PHP_SUBST(PHPDBG_EXTRA_LIBS) + + PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/phpdbg/Makefile.frag], [$abs_srcdir/sapi/phpdbg], [$abs_builddir/sapi/phpdbg]) 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) \ diff --git a/sapi/phpdbg/config.w32 b/sapi/phpdbg/config.w32 index 29031507b3..17e15b6ced 100644 --- a/sapi/phpdbg/config.w32 +++ b/sapi/phpdbg/config.w32 @@ -1,19 +1,19 @@ -ARG_ENABLE('phpdbg', 'Build phpdbg', 'yes'); +ARG_ENABLE('phpdbg', 'Build phpdbg', 'no'); 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_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_watch.c phpdbg_win.c phpdbg_btree.c phpdbg_parser.c phpdbg_lexer.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"); + SAPI('phpdbg', PHPDBG_SOURCES, PHPDBG_EXE); + ADD_FLAG("LIBS_PHPDBG", "ws2_32.lib user32.lib"); + ADD_FLAG("CFLAGS_PHPDBG", "/D YY_NO_UNISTD_H"); } 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"); + ADD_FLAG("CFLAGS_PHPDBGS", "/D YY_NO_UNISTD_H"); } - diff --git a/sapi/phpdbg/phpdbg.1 b/sapi/phpdbg/phpdbg.1 new file mode 100644 index 0000000000..5e4d144c83 --- /dev/null +++ b/sapi/phpdbg/phpdbg.1 @@ -0,0 +1,59 @@ +.TH PHPDBG 1 +.SH NAME +phpdbg \- The interactive PHP debugger +.SH SYNOPSIS +.B phpdbg +[OPTION] +[\fB\-e\fIFILE\fR] +.SH DESCRIPTION +.B phpdbg +a lightweight, powerful, easy to use debugging platform for PHP5. +.SH OPTIONS +The following switches are implemented (just like cli SAPI): +.TP +.BR \-n +No \fBphp.ini\fR file will be used +.TP +.BR \-c \fIpath\fB|\fIfile\fR +Look for \fBphp.ini\fR file in the directory \fIpath\fR or use the specified \fIfile\fR +.TP +.BR \-z \fIfile\fR +Load Zend extension \fIfile\fR +.TP +.BR \-d \fIfoo\fB[=\fIbar\fB]\fR +Define INI entry \fIfoo\fR with value \fIbar\fR +.PP The following switches change the default behaviour of phpdbg: +.TP +.BR \-v +Disables quietness +.TP +.BR \-s +Enabled stepping +.TP +.BR -e \fIfile\fR +Sets execution context +.TP +.BR \-b +Disables use of colour on the console +.TP +.BR \-I +Ignore .phpdbginit (default init file) +.TP +.BR \-i \fIpath\fB|\ffile\fR +Override .phpgdbinit location (implies -I) +.TP +.BR \-O \fIfile\fR +Set oplog output to \fIfile\fR +.TP +.BR \-q +Do not print banner on startup +.TP +.BR \-r +Jump straight to run +.TP +.BR \-E +Enable step through eval() +.SH NOTES +Passing -rr will cause phpdbg to quit after execution, rather than returning to the console +.SH AUTHOR +Written by Felipe Pena, Joe Watkins and Bob Weinand, formatted by OndÅ™ej Surý for Debian project. diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 51a328d0b5..1fbd18a423 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -#ifndef ZEND_SIGNALS +#if !defined(ZEND_SIGNALS) || defined(_WIN32) # include <signal.h> #endif #include "phpdbg.h" @@ -28,6 +28,7 @@ #include "phpdbg_list.h" #include "phpdbg_utils.h" #include "phpdbg_set.h" +#include "zend_alloc.h" /* {{{ remote console headers */ #ifndef _WIN32 @@ -61,16 +62,15 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->exec = NULL; pg->exec_len = 0; + pg->buffer = NULL; 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; } /* }}} */ @@ -145,6 +145,7 @@ static void php_phpdbg_destroy_registered(void *data) /* {{{ */ 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); @@ -157,7 +158,7 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */ 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); @@ -178,7 +179,14 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]); zend_hash_destroy(&PHPDBG_G(seek)); zend_hash_destroy(&PHPDBG_G(registered)); + zend_hash_destroy(&PHPDBG_G(watchpoints)); + zend_llist_destroy(&PHPDBG_G(watchlist_mem)); + if (PHPDBG_G(buffer)) { + efree(PHPDBG_G(buffer)); + PHPDBG_G(buffer) = NULL; + } + if (PHPDBG_G(exec)) { efree(PHPDBG_G(exec)); PHPDBG_G(exec) = NULL; @@ -209,24 +217,24 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ return SUCCESS; } /* }}} */ -/* {{{ proto mixed phpdbg_exec(string context) +/* {{{ 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 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) +static PHP_FUNCTION(phpdbg_exec) { char *exec = NULL; - zend_ulong exec_len = 0L; + int exec_len = 0; 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)) { @@ -234,11 +242,11 @@ static PHP_FUNCTION(phpdbg_exec) efree(PHPDBG_G(exec)); result = 0; } - + PHPDBG_G(exec) = estrndup(exec, exec_len); PHPDBG_G(exec_len) = exec_len; - - if (result) + + if (result) ZVAL_BOOL(return_value, 1); } else { zend_error( @@ -259,9 +267,9 @@ static PHP_FUNCTION(phpdbg_exec) static PHP_FUNCTION(phpdbg_break) { if (ZEND_NUM_ARGS() > 0) { - long type; + long type = 0; char *expr = NULL; - zend_uint expr_len = 0; + int expr_len = 0; phpdbg_param_t param; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &type, &expr, &expr_len) == FAILURE) { @@ -269,28 +277,7 @@ static PHP_FUNCTION(phpdbg_break) } 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_do_break(¶m TSRMLS_CC); phpdbg_clear_param(¶m TSRMLS_CC); } else if (EG(current_execute_data) && EG(active_op_array)) { @@ -319,9 +306,9 @@ static PHP_FUNCTION(phpdbg_clear) /* {{{ proto void phpdbg_color(integer element, string color) */ static PHP_FUNCTION(phpdbg_color) { - long element; - char *color; - zend_uint color_len; + long element = 0L; + char *color = NULL; + int color_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &element, &color, &color_len) == FAILURE) { return; @@ -341,8 +328,8 @@ static PHP_FUNCTION(phpdbg_color) /* {{{ proto void phpdbg_prompt(string prompt) */ static PHP_FUNCTION(phpdbg_prompt) { - char *prompt; - zend_uint prompt_len; + char *prompt = NULL; + int prompt_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &prompt, &prompt_len) == FAILURE) { return; @@ -403,9 +390,9 @@ 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; } /* }}} */ @@ -544,6 +531,69 @@ static inline void php_sapi_phpdbg_flush(void *context) /* {{{ */ fflush(PHPDBG_G(io)[PHPDBG_STDOUT]); } /* }}} */ +/* copied from sapi/cli/php_cli.c cli_register_file_handles */ +static void phpdbg_register_file_handles(TSRMLS_D) /* {{{ */ +{ + zval *zin, *zout, *zerr; + php_stream *s_in, *s_out, *s_err; + php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL; + zend_constant ic, oc, ec; + + MAKE_STD_ZVAL(zin); + MAKE_STD_ZVAL(zout); + MAKE_STD_ZVAL(zerr); + + s_in = php_stream_open_wrapper_ex("php://stdin", "rb", 0, NULL, sc_in); + s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out); + s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err); + + if (s_in==NULL || s_out==NULL || s_err==NULL) { + FREE_ZVAL(zin); + FREE_ZVAL(zout); + FREE_ZVAL(zerr); + if (s_in) php_stream_close(s_in); + if (s_out) php_stream_close(s_out); + if (s_err) php_stream_close(s_err); + return; + } + +#if PHP_DEBUG + /* do not close stdout and stderr */ + s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE; + s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE; +#endif + + php_stream_to_zval(s_in, zin); + php_stream_to_zval(s_out, zout); + php_stream_to_zval(s_err, zerr); + + ic.value = *zin; + ic.flags = CONST_CS; + ic.name = zend_strndup(ZEND_STRL("STDIN")); + ic.name_len = sizeof("STDIN"); + ic.module_number = 0; + zend_register_constant(&ic TSRMLS_CC); + + oc.value = *zout; + oc.flags = CONST_CS; + oc.name = zend_strndup(ZEND_STRL("STDOUT")); + oc.name_len = sizeof("STDOUT"); + oc.module_number = 0; + zend_register_constant(&oc TSRMLS_CC); + + ec.value = *zerr; + ec.flags = CONST_CS; + ec.name = zend_strndup(ZEND_STRL("STDERR")); + ec.name_len = sizeof("STDERR"); + ec.module_number = 0; + zend_register_constant(&ec TSRMLS_CC); + + FREE_ZVAL(zin); + FREE_ZVAL(zout); + FREE_ZVAL(zerr); +} +/* }}} */ + /* {{{ sapi_module_struct phpdbg_sapi_module */ static sapi_module_struct phpdbg_sapi_module = { @@ -585,7 +635,6 @@ const opt_struct OPTIONS[] = { /* {{{ */ {'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"}, @@ -615,10 +664,10 @@ const char phpdbg_ini_hardcoded[] = /* 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); + 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) /* {{{ */ { @@ -666,11 +715,11 @@ static inline void phpdbg_sigint_handler(int signo) /* {{{ */ 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; @@ -678,27 +727,27 @@ int phpdbg_open_socket(const char *interface, short port) /* {{{ */ 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); + 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); } @@ -707,28 +756,28 @@ int phpdbg_open_socket(const char *interface, short port) /* {{{ */ } } } - + 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]); } @@ -798,16 +847,64 @@ int phpdbg_open_sockets(char *address, int port[2], int (*listen)[2], int (*sock 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; } /* }}} */ + +void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */ +{ + int is_handled = FAILURE; + TSRMLS_FETCH(); + + switch (sig) { + case SIGBUS: + case SIGSEGV: + is_handled = phpdbg_watchpoint_segfault_handler(info, context TSRMLS_CC); + if (is_handled == FAILURE) { +#ifdef ZEND_SIGNALS + zend_sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL TSRMLS_CC); +#else + sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL); +#endif + } + break; + } + +} /* }}} */ #endif +static inline zend_mm_heap *phpdbg_mm_get_heap() /* {{{ */ +{ + zend_mm_heap *mm_heap; + + TSRMLS_FETCH(); + + mm_heap = zend_mm_set_heap(NULL TSRMLS_CC); + zend_mm_set_heap(mm_heap TSRMLS_CC); + + return mm_heap; +} /* }}} */ + +void *phpdbg_malloc_wrapper(size_t size) /* {{{ */ +{ + return zend_mm_alloc(phpdbg_mm_get_heap(), size); +} /* }}} */ + +void phpdbg_free_wrapper(void *p) /* {{{ */ +{ + zend_mm_free(phpdbg_mm_get_heap(), p); +} /* }}} */ + +void *phpdbg_realloc_wrapper(void *ptr, size_t size) /* {{{ */ +{ + return zend_mm_realloc(phpdbg_mm_get_heap(), ptr, size); +} /* }}} */ + int main(int argc, char **argv) /* {{{ */ { sapi_module_struct *phpdbg = &phpdbg_sapi_module; @@ -852,6 +949,10 @@ int main(int argc, char **argv) /* {{{ */ #endif #ifndef _WIN32 + struct sigaction signal_struct; + signal_struct.sa_sigaction = phpdbg_signal_handler; + signal_struct.sa_flags = SA_SIGINFO | SA_NODEFER; + address = strdup("127.0.0.1"); socket[0] = -1; socket[1] = -1; @@ -888,17 +989,17 @@ phpdbg_main: bp_tmp_file = NULL; } } + + if (!bp_tmp_file) { + phpdbg_error("Unable to create temporary file"); + return 1; + } #else if (!mkstemp(bp_tmp_file)) { memset(bp_tmp_file, 0, sizeof(bp_tmp_file)); } #endif - if (!bp_tmp_file) { - phpdbg_error( - "Unable to create temporary file"); - return 1; - } } ini_entries = NULL; ini_entries_len = 0; @@ -920,8 +1021,7 @@ phpdbg_main: 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': @@ -965,7 +1065,7 @@ phpdbg_main: ini_entries_len += len + sizeof("=1\n\0") - 2; } } break; - + case 'z': zend_extensions_len++; if (zend_extensions) { @@ -976,16 +1076,6 @@ phpdbg_main: /* 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); @@ -1001,7 +1091,7 @@ phpdbg_main: if (init_file) { free(init_file); } - + init_file_len = strlen(php_optarg); if (init_file_len) { init_file = strdup(php_optarg); @@ -1038,7 +1128,7 @@ phpdbg_main: #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) { @@ -1050,7 +1140,7 @@ phpdbg_main: } } } break; - + case 'a': { /* set bind address */ free(address); if (!php_optarg) { @@ -1076,6 +1166,19 @@ phpdbg_main: } break; } } + + /* set exec if present on command line */ + if ((argc > php_optind) && (strcmp(argv[php_optind-1],"--") != SUCCESS)) + { + exec_len = strlen(argv[php_optind]); + if (exec_len) { + if (exec) { + free(exec); + } + exec = strdup(argv[php_optind]); + } + php_optind++; + } #ifndef _WIN32 /* setup remote server if necessary */ @@ -1093,7 +1196,7 @@ phpdbg_main: if (sapi_name) { phpdbg->name = sapi_name; } - + phpdbg->ini_defaults = phpdbg_ini_defaults; phpdbg->phpinfo_as_text = 1; phpdbg->php_ini_ignore_cwd = 1; @@ -1114,14 +1217,14 @@ phpdbg_main: 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)); @@ -1133,40 +1236,80 @@ phpdbg_main: free(zend_extensions[zend_extension]); zend_extension++; } - + free(zend_extensions); } phpdbg->ini_entries = ini_entries; - + if (phpdbg->startup(phpdbg) == SUCCESS) { - php_request_startup(TSRMLS_C); +#ifdef _WIN32 + EXCEPTION_POINTERS *xp; + __try { +#endif + zend_mm_heap *mm_heap = phpdbg_mm_get_heap(); + + if (mm_heap->use_zend_alloc) { + mm_heap->_malloc = phpdbg_malloc_wrapper; + mm_heap->_realloc = phpdbg_realloc_wrapper; + mm_heap->_free = phpdbg_free_wrapper; + mm_heap->use_zend_alloc = 0; + } + + zend_activate(TSRMLS_C); + + PHPDBG_G(original_free_function) = mm_heap->_free; + mm_heap->_free = phpdbg_watch_efree; + + phpdbg_setup_watchpoints(TSRMLS_C); + +#if defined(ZEND_SIGNALS) && !defined(_WIN32) + zend_try { + zend_signal_activate(TSRMLS_C); + } zend_end_try(); +#endif + +#if defined(ZEND_SIGNALS) && !defined(_WIN32) + zend_try { zend_sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal) TSRMLS_CC); } zend_end_try(); + zend_try { zend_sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal) TSRMLS_CC); } zend_end_try(); +#elif !defined(_WIN32) + sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); + sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); +#endif + + if (php_request_startup(TSRMLS_C) == SUCCESS) { + int i; + + SG(request_info).argc = argc - php_optind + 1; + SG(request_info).argv = emalloc(SG(request_info).argc * sizeof(char *)); + for (i = SG(request_info).argc; --i;) { + SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]); + } + SG(request_info).argv[i] = exec ? estrndup(exec, exec_len) : estrdup(""); + + php_hash_environment(TSRMLS_C); + } + + /* make sure to turn off buffer for ev command */ + php_output_activate(TSRMLS_C); + php_output_deactivate(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 defined(ZEND_SIGNALS) && !defined(_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 + zend_try { zend_signal(SIGINT, phpdbg_sigint_handler TSRMLS_CC); } zend_end_try(); } -# endif -#else -# ifndef _WIN32 +#elif !defined(_WIN32) if (listen[0] < 0) { -# endif +#endif signal(SIGINT, phpdbg_sigint_handler); #ifndef _WIN32 } #endif -#endif PG(modules_activated) = 0; - + /* set flags from command line */ PHPDBG_G(flags) = flags; @@ -1182,10 +1325,9 @@ phpdbg_main: 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) = phpdbg_resolve_path(exec TSRMLS_CC); PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec)); free(exec); @@ -1208,11 +1350,19 @@ phpdbg_main: /* set default prompt */ phpdbg_set_prompt(PROMPT TSRMLS_CC); + /* Make stdin, stdout and stderr accessible from PHP scripts */ + phpdbg_register_file_handles(TSRMLS_C); + if (show_banner) { /* print blurb */ phpdbg_welcome((cleaning > 0) TSRMLS_CC); } + /* auto compile */ + if (PHPDBG_G(exec)) { + phpdbg_compile(TSRMLS_C); + } + /* initialize from file */ PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING; zend_try { @@ -1233,14 +1383,17 @@ phpdbg_main: if (run) { /* no need to try{}, run does it ... */ - PHPDBG_COMMAND_HANDLER(run)(NULL, NULL TSRMLS_CC); + PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC); if (run > 1) { /* if -r is on the command line more than once just quit */ goto phpdbg_out; } } +/* #ifndef for making compiler shutting up */ +#ifndef _WIN32 phpdbg_interact: +#endif /* phpdbg main() */ do { zend_try { @@ -1282,21 +1435,42 @@ phpdbg_interact: } zend_end_try(); } while(!cleaning && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); -phpdbg_out: + /* this must be forced */ + CG(unclean_shutdown) = 0; + + /* this is just helpful */ + PG(report_memleaks) = 0; + #ifndef _WIN32 +phpdbg_out: if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) { PHPDBG_G(flags) &= ~PHPDBG_IS_DISCONNECTED; goto phpdbg_interact; } #endif +#ifdef _WIN32 + } __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) { + phpdbg_error("Access violation (Segementation fault) encountered\ntrying to abort cleanly..."); + } +phpdbg_out: +#endif + + { + int i; + /* free argv */ + for (i = SG(request_info).argc; --i;) { + efree(SG(request_info).argv[i]); + } + efree(SG(request_info).argv); + } + #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); } @@ -1318,6 +1492,7 @@ phpdbg_out: } zend_end_try(); sapi_shutdown(); + } if (cleaning || remote) { @@ -1331,7 +1506,7 @@ phpdbg_out: #ifndef _WIN32 if (address) { - free(address); + free(address); } #endif diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h index 68c505ca63..eb4faf1f94 100644 --- a/sapi/phpdbg/phpdbg.h +++ b/sapi/phpdbg/phpdbg.h @@ -39,6 +39,9 @@ #include "zend_globals.h" #include "zend_ini_scanner.h" #include "zend_stream.h" +#ifndef _WIN32 +# include "zend_signal.h" +#endif #include "SAPI.h" #include <fcntl.h> #include <sys/types.h> @@ -61,13 +64,21 @@ # include "TSRM.h" #endif -#ifdef HAVE_LIBREADLINE +#ifdef LIBREADLINE # include <readline/readline.h> # include <readline/history.h> #endif +#ifdef HAVE_LIBEDIT +# include <editline/readline.h> +#endif +#include "phpdbg_lexer.h" #include "phpdbg_cmd.h" #include "phpdbg_utils.h" +#include "phpdbg_btree.h" +#include "phpdbg_watch.h" + +int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC); #ifdef ZTS # define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v) @@ -116,23 +127,26 @@ #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_STEP_OPCODE (1<<13) +#define PHPDBG_IS_QUIET (1<<14) +#define PHPDBG_IS_QUITTING (1<<15) +#define PHPDBG_IS_COLOURED (1<<16) +#define PHPDBG_IS_CLEANING (1<<17) + +#define PHPDBG_IN_UNTIL (1<<18) +#define PHPDBG_IN_FINISH (1<<19) +#define PHPDBG_IN_LEAVE (1<<20) + +#define PHPDBG_IS_REGISTERED (1<<21) +#define PHPDBG_IS_STEPONEVAL (1<<22) +#define PHPDBG_IS_INITIALIZING (1<<23) +#define PHPDBG_IS_SIGNALED (1<<24) +#define PHPDBG_IS_INTERACTIVE (1<<25) +#define PHPDBG_IS_BP_ENABLED (1<<26) +#define PHPDBG_IS_REMOTE (1<<27) +#define PHPDBG_IS_DISCONNECTED (1<<28) + +#define PHPDBG_SHOW_REFCOUNTS (1<<29) #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) @@ -149,7 +163,7 @@ #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.2" +#define PHPDBG_VERSION "0.4.0" #define PHPDBG_INIT_FILENAME ".phpdbginit" /* }}} */ @@ -159,12 +173,27 @@ #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 */ + zend_uint last_line; /* last executed line */ + + phpdbg_lexer_data lexer; /* lexer data */ + phpdbg_param_t *parser_stack; /* param stack during lexer / parser phase */ + +#ifndef _WIN32 + struct sigaction old_sigsegv_signal; /* segv signal handler */ +#endif + phpdbg_btree watchpoint_tree; /* tree with watchpoints */ + phpdbg_btree watch_HashTables; /* tree with original dtors of watchpoints */ + HashTable watchpoints; /* watchpoints */ + zend_llist watchlist_mem; /* triggered watchpoints */ + zend_bool watchpoint_hit; /* a watchpoint was hit */ + void (*original_free_function)(void *); /* the original AG(mm_heap)->_free function */ char *exec; /* file to execute */ size_t exec_len; /* size of exec */ @@ -178,11 +207,24 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) char *prompt[2]; /* prompt */ const phpdbg_color_t *colors[PHPDBG_COLORS]; /* colors */ - - phpdbg_command_t *lcmd; /* last command */ - phpdbg_param_t lparam; /* last param */ + char *buffer; /* buffer */ zend_ulong flags; /* phpdbg flags */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ +/* the beginning (= the important part) of the _zend_mm_heap struct defined in Zend/zend_alloc.c + Needed for realizing watchpoints */ +struct _zend_mm_heap { + int use_zend_alloc; + void *(*_malloc)(size_t); + void (*_free)(void *); + void *(*_realloc)(void *, size_t); + size_t free_bitmap; + size_t large_free_bitmap; + size_t block_size; + size_t compact_size; + zend_mm_segment *segments_list; + zend_mm_storage *storage; +}; + #endif /* PHPDBG_H */ diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c index 511d1db57d..a18316a228 100644 --- a/sapi/phpdbg/phpdbg_bp.c +++ b/sapi/phpdbg/phpdbg_bp.c @@ -135,27 +135,27 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ switch (brake->type) { case PHPDBG_BREAK_FILE: { fprintf(handle, - "break file %s:%lu\n", + "break %s:%lu\n", ((phpdbg_breakfile_t*)brake)->filename, ((phpdbg_breakfile_t*)brake)->line); } break; case PHPDBG_BREAK_SYM: { fprintf(handle, - "break func %s\n", + "break %s\n", ((phpdbg_breaksymbol_t*)brake)->symbol); } break; case PHPDBG_BREAK_METHOD: { fprintf(handle, - "break method %s::%s\n", + "break %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", + "break %s::%s#%ld\n", ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->func_name, ((phpdbg_breakopline_t*)brake)->opline_num); @@ -163,21 +163,21 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ case PHPDBG_BREAK_FUNCTION_OPLINE: { fprintf(handle, - "break address %s#%ld\n", + "break %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", + "break %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", + "break %s\n", ((phpdbg_breakop_t*)brake)->name); } break; @@ -209,7 +209,7 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ } } else { fprintf( - handle, "break on %s\n", conditional->code); + handle, "break if %s\n", conditional->code); } } break; } @@ -221,14 +221,20 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ 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)) { + php_stream_statbuf ssb; + char realpath[MAXPATHLEN]; + + if (php_stream_stat_path(path, &ssb) != FAILURE) { + if (ssb.sb.st_mode & (S_IFREG|S_IFLNK)) { HashTable *broken; phpdbg_breakfile_t new_break; - size_t path_len = strlen(path); - + size_t path_len = 0L; + + if (VCWD_REALPATH(path, realpath)) { + path = realpath; + } + path_len = strlen(path); + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len, (void**)&broken) == FAILURE) { HashTable breaks; @@ -324,9 +330,9 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char PHPDBG_BREAK_MAPPING(new_break.id, class_table); } else { phpdbg_notice("Breakpoint exists at %s::%s", class_name, func_name); - } + } - efree(lcname); + efree(lcname); } /* }}} */ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ */ @@ -355,7 +361,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ 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 (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) { @@ -760,56 +766,26 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_l } } /* }}} */ -PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param, const phpdbg_input_t *input TSRMLS_DC) /* {{{ */ +PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param 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_breakcond_t new_break; + phpdbg_param_t *condition; + zend_ulong hash = 0L; + + if (param->next) { + condition = param->next; + hash = zend_inline_hash_func(condition->str, condition->len); + + if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash)) { phpdbg_create_conditional_break( - &new_break, &new_param, expr, expr_len, expr_hash TSRMLS_CC); + &new_break, param, + condition->str, condition->len, 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 <func|method|file:line|address> if <expression>"); + "Conditional break %s exists at the specified location", condition->str); + } } + } /* }}} */ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */ @@ -992,7 +968,7 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut 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)) { + 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); diff --git a/sapi/phpdbg/phpdbg_bp.h b/sapi/phpdbg/phpdbg_bp.h index b1a9ddf474..97980e7ed7 100644 --- a/sapi/phpdbg/phpdbg_bp.h +++ b/sapi/phpdbg/phpdbg_bp.h @@ -119,7 +119,7 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha 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); /* }}} */ +PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param TSRMLS_DC); /* }}} */ /* {{{ Breakpoint Detection API */ PHPDBG_API phpdbg_breakbase_t* phpdbg_find_breakpoint(zend_execute_data* TSRMLS_DC); /* }}} */ diff --git a/sapi/phpdbg/phpdbg_break.c b/sapi/phpdbg/phpdbg_break.c index f56f76facd..be76b22b05 100644 --- a/sapi/phpdbg/phpdbg_break.c +++ b/sapi/phpdbg/phpdbg_break.c @@ -24,132 +24,32 @@ #include "phpdbg_opcode.h" #include "phpdbg_break.h" #include "phpdbg_bp.h" +#include "phpdbg_prompt.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; +#define PHPDBG_BREAK_COMMAND_D(f, h, a, m, l, s) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[10]) - 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; -} /* }}} */ +/** + * Commands + */ +const phpdbg_command_t phpdbg_break_commands[] = { + PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", '@', break_at, NULL, "*c"), + PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", '~', break_del, NULL, "n"), + PHPDBG_END_COMMAND +}; 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(); - } + phpdbg_set_breakpoint_at(param TSRMLS_CC); return SUCCESS; } /* }}} */ PHPDBG_BREAK(del) /* {{{ */ { - switch (param->type) { - case NUMERIC_PARAM: { - phpdbg_delete_breakpoint(param->num TSRMLS_CC); - } break; - - phpdbg_default_switch_case(); - } + phpdbg_delete_breakpoint(param->num TSRMLS_CC); return SUCCESS; } /* }}} */ diff --git a/sapi/phpdbg/phpdbg_break.h b/sapi/phpdbg/phpdbg_break.h index f90e351d6d..dc06da62b7 100644 --- a/sapi/phpdbg/phpdbg_break.h +++ b/sapi/phpdbg/phpdbg_break.h @@ -29,30 +29,9 @@ /** * 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 -}; +extern const phpdbg_command_t phpdbg_break_commands[]; #endif /* PHPDBG_BREAK_H */ diff --git a/sapi/phpdbg/phpdbg_btree.c b/sapi/phpdbg/phpdbg_btree.c new file mode 100644 index 0000000000..491445399b --- /dev/null +++ b/sapi/phpdbg/phpdbg_btree.c @@ -0,0 +1,221 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 <felipe@php.net> | + | Authors: Joe Watkins <joe.watkins@live.co.uk> | + | Authors: Bob Weinand <bwoebi@php.net> | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg_btree.h" +#include "phpdbg.h" + +#define CHOOSE_BRANCH(n) \ + branch = branch->branches[!!(n)]; + +#ifdef _Win32 +# define emalloc malloc +# define efree free +#endif + +/* depth in bits */ +void phpdbg_btree_init(phpdbg_btree *tree, zend_ulong depth) { + tree->depth = depth; + tree->branch = NULL; + tree->count = 0; +} + +phpdbg_btree_result *phpdbg_btree_find(phpdbg_btree *tree, zend_ulong idx) { + phpdbg_btree_branch *branch = tree->branch; + int i = tree->depth - 1; + + if (branch == NULL) { + return NULL; + } + + do { + if ((idx >> i) % 2 == 1) { + if (branch->branches[1]) { + CHOOSE_BRANCH(1); + } else { + return NULL; + } + } else { + if (branch->branches[0]) { + CHOOSE_BRANCH(0); + } else { + return NULL; + } + } + } while (i--); + + return &branch->result; +} + +phpdbg_btree_result *phpdbg_btree_find_closest(phpdbg_btree *tree, zend_ulong idx) { + phpdbg_btree_branch *branch = tree->branch; + int i = tree->depth - 1, last_superior_i = -1; + zend_bool had_alternative_branch = 0; + + if (branch == NULL) { + return NULL; + } + + /* find nearest watchpoint */ + do { + /* an impossible branch was found if: */ + if (!had_alternative_branch && (idx >> i) % 2 == 0 && !branch->branches[0]) { + /* there's no lower branch than idx */ + if (last_superior_i == -1) { + /* failure */ + return NULL; + } + /* reset state */ + branch = tree->branch; + i = tree->depth - 1; + /* follow branch according to bits in idx until the last lower branch before the impossible branch */ + do { + CHOOSE_BRANCH((idx >> i) % 2 == 1 && branch->branches[1]); + } while (--i > last_superior_i); + /* use now the lower branch of which we can be sure that it contains only branches lower than idx */ + CHOOSE_BRANCH(0); + /* and choose the highest possible branch in the branch containing only branches lower than idx */ + while (i--) { + CHOOSE_BRANCH(branch->branches[1]); + } + break; + } + /* follow branch according to bits in idx until having found an impossible branch */ + if (had_alternative_branch || (idx >> i) % 2 == 1) { + if (branch->branches[1]) { + if (branch->branches[0]) { + last_superior_i = i; + } + CHOOSE_BRANCH(1); + } else { + CHOOSE_BRANCH(0); + had_alternative_branch = 1; + } + } else { + CHOOSE_BRANCH(0); + } + } while (i--); + + return &branch->result; +} + +phpdbg_btree_position phpdbg_btree_find_between(phpdbg_btree *tree, zend_ulong lower_idx, zend_ulong higher_idx) { + phpdbg_btree_position pos; + + pos.tree = tree; + pos.end = lower_idx; + pos.cur = higher_idx; + + return pos; +} + +phpdbg_btree_result *phpdbg_btree_next(phpdbg_btree_position *pos) { + phpdbg_btree_result *result = phpdbg_btree_find_closest(pos->tree, pos->cur); + + if (result == NULL || result->idx < pos->end) { + return NULL; + } + + pos->cur = result->idx - 1; + + return result; +} + +int phpdbg_btree_insert_or_update(phpdbg_btree *tree, zend_ulong idx, void *ptr, int flags) { + int i = tree->depth - 1; + phpdbg_btree_branch **branch = &tree->branch; + + do { + if (*branch == NULL) { + break; + } + branch = &(*branch)->branches[(idx >> i) % 2]; + } while (i--); + + if (*branch == NULL) { + if (!(flags & PHPDBG_BTREE_INSERT)) { + return FAILURE; + } + + { + phpdbg_btree_branch *memory = *branch = emalloc((i + 2) * sizeof(phpdbg_btree_branch)); + do { + (*branch)->branches[!((idx >> i) % 2)] = NULL; + branch = &(*branch)->branches[(idx >> i) % 2]; + *branch = ++memory; + } while (i--); + tree->count++; + } + } else if (!(flags & PHPDBG_BTREE_UPDATE)) { + return FAILURE; + } + + (*branch)->result.idx = idx; + (*branch)->result.ptr = ptr; + + return SUCCESS; +} + +int phpdbg_btree_delete(phpdbg_btree *tree, zend_ulong idx) { + int i = tree->depth; + phpdbg_btree_branch *branch = tree->branch; + int i_last_dual_branch = -1, last_dual_branch_branch; + phpdbg_btree_branch *last_dual_branch = NULL; + + goto check_branch_existence; + do { + if (branch->branches[0] && branch->branches[1]) { + last_dual_branch = branch; + i_last_dual_branch = i; + last_dual_branch_branch = (idx >> i) % 2; + } + branch = branch->branches[(idx >> i) % 2]; + +check_branch_existence: + if (branch == NULL) { + return FAILURE; + } + } while (i--); + + tree->count--; + + if (i_last_dual_branch == -1) { + efree(tree->branch); + tree->branch = NULL; + } else { + if (last_dual_branch->branches[last_dual_branch_branch] == last_dual_branch + 1) { + phpdbg_btree_branch *original_branch = last_dual_branch->branches[!last_dual_branch_branch]; + + memcpy(last_dual_branch + 1, last_dual_branch->branches[!last_dual_branch_branch], (i_last_dual_branch + 1) * sizeof(phpdbg_btree_branch)); + efree(last_dual_branch->branches[!last_dual_branch_branch]); + last_dual_branch->branches[!last_dual_branch_branch] = last_dual_branch + 1; + + branch = last_dual_branch->branches[!last_dual_branch_branch]; + for (i = i_last_dual_branch; i--;) { + branch = (branch->branches[branch->branches[1] == ++original_branch] = last_dual_branch + i_last_dual_branch - i + 1); + } + } else { + efree(last_dual_branch->branches[last_dual_branch_branch]); + } + + last_dual_branch->branches[last_dual_branch_branch] = NULL; + } + + return SUCCESS; +} diff --git a/sapi/phpdbg/phpdbg_btree.h b/sapi/phpdbg/phpdbg_btree.h new file mode 100644 index 0000000000..af2a6ac314 --- /dev/null +++ b/sapi/phpdbg/phpdbg_btree.h @@ -0,0 +1,65 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 <felipe@php.net> | + | Authors: Joe Watkins <joe.watkins@live.co.uk> | + | Authors: Bob Weinand <bwoebi@php.net> | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_BTREE_H +#define PHPDBG_BTREE_H + +#include "zend.h" + +typedef struct { + zend_ulong idx; + void *ptr; +} phpdbg_btree_result; + +typedef union _phpdbg_btree_branch phpdbg_btree_branch; +union _phpdbg_btree_branch { + phpdbg_btree_branch *branches[2]; + phpdbg_btree_result result; +}; + +typedef struct { + zend_ulong count; + zend_ulong depth; + phpdbg_btree_branch *branch; +} phpdbg_btree; + +typedef struct { + phpdbg_btree *tree; + zend_ulong cur; + zend_ulong end; +} phpdbg_btree_position; + +void phpdbg_btree_init(phpdbg_btree *tree, zend_ulong depth); +phpdbg_btree_result *phpdbg_btree_find(phpdbg_btree *tree, zend_ulong idx); +phpdbg_btree_result *phpdbg_btree_find_closest(phpdbg_btree *tree, zend_ulong idx); +phpdbg_btree_position phpdbg_btree_find_between(phpdbg_btree *tree, zend_ulong lower_idx, zend_ulong higher_idx); +phpdbg_btree_result *phpdbg_btree_next(phpdbg_btree_position *pos); +int phpdbg_btree_delete(phpdbg_btree *tree, zend_ulong idx); + +#define PHPDBG_BTREE_INSERT 1 +#define PHPDBG_BTREE_UPDATE 2 +#define PHPDBG_BTREE_OVERWRITE (PHPDBG_BTREE_INSERT | PHPDBG_BTREE_UPDATE) + +int phpdbg_btree_insert_or_update(phpdbg_btree *tree, zend_ulong idx, void *ptr, int flags); +#define phpdbg_btree_insert(tree, idx, ptr) phpdbg_btree_insert_or_update(tree, idx, ptr, PHPDBG_BTREE_INSERT) +#define phpdbg_btree_update(tree, idx, ptr) phpdbg_btree_insert_or_update(tree, idx, ptr, PHPDBG_BTREE_UPDATE) +#define phpdbg_btree_overwrite(tree, idx, ptr) phpdbg_btree_insert_or_update(tree, idx, ptr, PHPDBG_BTREE_OWERWRITE) + +#endif diff --git a/sapi/phpdbg/phpdbg_cmd.c b/sapi/phpdbg/phpdbg_cmd.c index 1d78c53321..a45513bee6 100644 --- a/sapi/phpdbg/phpdbg_cmd.c +++ b/sapi/phpdbg/phpdbg_cmd.c @@ -22,12 +22,32 @@ #include "phpdbg_cmd.h" #include "phpdbg_utils.h" #include "phpdbg_set.h" +#include "phpdbg_prompt.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +static inline const char *phpdbg_command_name(const phpdbg_command_t *command, char *buffer) { + size_t pos = 0; + + if (command->parent) { + memcpy(&buffer[pos], command->parent->name, command->parent->name_len); + pos += command->parent->name_len; + memcpy(&buffer[pos], " ", sizeof(" ")-1); + pos += (sizeof(" ")-1); + } + + memcpy(&buffer[pos], command->name, command->name_len); + pos += command->name_len; + buffer[pos] = 0; + + return buffer; +} + PHPDBG_API const char *phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */ { switch (param->type) { + case STACK_PARAM: + return "stack"; case EMPTY_PARAM: return "empty"; case ADDR_PARAM: @@ -208,10 +228,19 @@ PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **point PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* dest TSRMLS_DC) /* {{{ */ { switch ((dest->type = src->type)) { + case STACK_PARAM: + /* nope */ + break; + case STR_PARAM: dest->str = estrndup(src->str, src->len); dest->len = src->len; break; + + case OP_PARAM: + dest->str = estrndup(src->str, src->len); + dest->len = src->len; + break; case ADDR_PARAM: dest->addr = src->addr; @@ -226,6 +255,7 @@ PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* des dest->method.name = estrdup(src->method.name); break; + case NUMERIC_FILE_PARAM: case FILE_PARAM: dest->file.name = estrdup(src->file.name); dest->file.line = src->file.line; @@ -246,6 +276,10 @@ PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* des break; case EMPTY_PARAM: { /* do nothing */ } break; + + default: { + /* not yet */ + } } } /* }}} */ @@ -254,6 +288,10 @@ PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *param TSRMLS_DC) / zend_ulong hash = param->type; switch (param->type) { + case STACK_PARAM: + /* nope */ + break; + case STR_PARAM: hash += zend_inline_hash_func(param->str, param->len); break; @@ -291,6 +329,10 @@ PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *param TSRMLS_DC) / break; case EMPTY_PARAM: { /* do nothing */ } break; + + default: { + /* not yet */ + } } return hash; @@ -301,7 +343,11 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_pa if (l && r) { if (l->type == r->type) { switch (l->type) { - + case STACK_PARAM: + /* nope, or yep */ + return 1; + break; + case NUMERIC_FUNCTION_PARAM: if (l->num != r->num) { break; @@ -356,112 +402,400 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_pa case EMPTY_PARAM: return 1; + + default: { + /* not yet */ + } } } } 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; +/* {{{ */ +PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) { + if (param && param->type) { + switch (param->type) { + case STR_PARAM: + fprintf(stderr, "%s STR_PARAM(%s=%lu)\n", msg, param->str, param->len); + break; + + case ADDR_PARAM: + fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr); + break; + + case NUMERIC_FILE_PARAM: + fprintf(stderr, "%s NUMERIC_FILE_PARAM(%s:#%lu)\n", msg, param->file.name, param->file.line); + break; + + case FILE_PARAM: + fprintf(stderr, "%s FILE_PARAM(%s:%lu)\n", msg, param->file.name, param->file.line); + break; + + case METHOD_PARAM: + fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); + break; + + case NUMERIC_METHOD_PARAM: + fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); + break; + + case NUMERIC_FUNCTION_PARAM: + fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%ld)\n", msg, param->str, param->num); + break; + + case NUMERIC_PARAM: + fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); + break; + + case COND_PARAM: + fprintf(stderr, "%s COND_PARAM(%s=%lu)\n", msg, param->str, param->len); + break; + + case OP_PARAM: + fprintf(stderr, "%s OP_PARAM(%s=%lu)\n", msg, param->str, param->len); + break; + + default: { + /* not yet */ + } + } + } +} /* }}} */ - case IN_WORD: - if (isspace(c)) { - RESET_STATE(); - } else { - b[l++]=c; +/* {{{ */ +PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack) { + if (stack && stack->next) { + phpdbg_param_t *remove = stack->next; + + while (remove) { + phpdbg_param_t *next = NULL; + + if (remove->next) + next = remove->next; + + switch (remove->type) { + case NUMERIC_METHOD_PARAM: + case METHOD_PARAM: + if (remove->method.class) + free(remove->method.class); + if (remove->method.name) + free(remove->method.name); + break; + + case NUMERIC_FUNCTION_PARAM: + case STR_PARAM: + case OP_PARAM: + if (remove->str) + free(remove->str); + break; + + case NUMERIC_FILE_PARAM: + case FILE_PARAM: + if (remove->file.name) + free(remove->file.name); + break; + + default: { + /* nothing */ } - continue; + } + + free(remove); + remove = NULL; + + if (next) + remove = next; + else break; } } + + stack->next = NULL; +} /* }}} */ - switch (state) { - case IN_WORD: { - RESET_STATE(); - } break; +/* {{{ */ +PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { + phpdbg_param_t *next = calloc(1, sizeof(phpdbg_param_t)); - case IN_STRING: - phpdbg_error( - "Malformed command line (unclosed quote) @ %ld: %s!", - (p - buffer)-1, &buffer[(p - buffer)-1]); - break; + if (!next) + return; - case IN_BETWEEN: - break; + *(next) = *(param); + + next->next = NULL; + + if (stack->top == NULL) { + stack->top = next; + next->top = NULL; + stack->next = next; + } else { + stack->top->next = next; + next->top = stack->top; + stack->top = next; } - if ((*argc) == 0) { - /* not needed */ - efree(argv); + stack->len++; +} /* }}} */ - /* to be sure */ - return NULL; +PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC) { + if (command) { + char buffer[128] = {0,}; + const phpdbg_param_t *top = (stack != NULL) ? *stack : NULL; + const char *arg = command->args; + size_t least = 0L, + received = 0L, + current = 0L; + zend_bool optional = 0; + + /* check for arg spec */ + if (!(arg) || !(*arg)) { + if (!top) { + return SUCCESS; + } + + asprintf(why, + "The command \"%s\" expected no arguments", + phpdbg_command_name(command, buffer)); + return FAILURE; + } + + least = 0L; + + /* count least amount of arguments */ + while (arg && *arg) { + if (arg[0] == '|') { + break; + } + least++; + arg++; + } + + arg = command->args; + +#define verify_arg(e, a, t) if (!(a)) { \ + if (!optional) { \ + asprintf(why, \ + "The command \"%s\" expected %s and got nothing at parameter %lu", \ + phpdbg_command_name(command, buffer), \ + (e), \ + current); \ + return FAILURE;\ + } \ +} else if ((a)->type != (t)) { \ + asprintf(why, \ + "The command \"%s\" expected %s and got %s at parameter %lu", \ + phpdbg_command_name(command, buffer), \ + (e),\ + phpdbg_get_param_type((a) TSRMLS_CC), \ + current); \ + return FAILURE; \ +} + + while (arg && *arg) { + current++; + + switch (*arg) { + case '|': { + current--; + optional = 1; + arg++; + } continue; + + case 'i': verify_arg("raw input", top, STR_PARAM); break; + case 's': verify_arg("string", top, STR_PARAM); break; + case 'n': verify_arg("number", top, NUMERIC_PARAM); break; + case 'm': verify_arg("method", top, METHOD_PARAM); break; + case 'a': verify_arg("address", top, ADDR_PARAM); break; + case 'f': verify_arg("file:line", top, FILE_PARAM); break; + case 'c': verify_arg("condition", top, COND_PARAM); break; + case 'o': verify_arg("opcode", top, OP_PARAM); break; + case 'b': verify_arg("boolean", top, NUMERIC_PARAM); break; + + case '*': { /* do nothing */ } break; + } + + if (top ) { + top = top->next; + } else break; + + received++; + arg++; + } + +#undef verify_arg + + if ((received < least)) { + asprintf(why, + "The command \"%s\" expected at least %lu arguments (%s) and received %lu", + phpdbg_command_name(command, buffer), + least, + command->args, + received); + return FAILURE; + } } + + return SUCCESS; +} + +/* {{{ */ +PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why) { + const phpdbg_command_t *command = commands; + phpdbg_param_t *name = *top; + const phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; + ulong matches = 0L; + + while (command && command->name && command->handler) { + if ((name->len == 1) || (command->name_len >= name->len)) { + /* match single letter alias */ + if (command->alias && (name->len == 1)) { + if (command->alias == (*name->str)) { + matched[matches] = command; + matches++; + } + } else { - return argv; + /* match full, case insensitive, command name */ + if (strncasecmp(command->name, name->str, name->len) == SUCCESS) { + if (matches < 3) { + + /* only allow abbreviating commands that can be aliased */ + if (((name->len != command->name_len) && command->alias) || + (name->len == command->name_len)) { + matched[matches] = command; + matches++; + } + + + /* exact match */ + if (name->len == command->name_len) + break; + } else break; + } + } + } + + command++; + } + + switch (matches) { + case 0: { + if (parent) { + asprintf( + why, + "The command \"%s %s\" could not be found", + parent->name, name->str); + } else asprintf( + why, + "The command \"%s\" could not be found", + name->str); + } return parent; + + case 1: { + (*top) = (*top)->next; + + command = matched[0]; + } break; + + default: { + char *list = NULL; + zend_uint it = 0; + size_t pos = 0; + + while (it < matches) { + if (!list) { + list = malloc( + matched[it]->name_len + 1 + + ((it+1) < matches ? sizeof(", ")-1 : 0)); + } else { + list = realloc(list, + (pos + matched[it]->name_len) + 1 + + ((it+1) < matches ? sizeof(", ")-1 : 0)); + } + memcpy(&list[pos], matched[it]->name, matched[it]->name_len); + pos += matched[it]->name_len; + if ((it+1) < matches) { + memcpy(&list[pos], ", ", sizeof(", ")-1); + pos += (sizeof(", ") - 1); + } + + list[pos] = 0; + it++; + } + + asprintf( + why, + "The command \"%s\" is ambigious, matching %lu commands (%s)", + name->str, matches, list); + free(list); + } return NULL; + } + + if (command->subs && (*top) && ((*top)->type == STR_PARAM)) { + return phpdbg_stack_resolve(command->subs, command, top, why); + } else { + return command; + } + + return NULL; } /* }}} */ -PHPDBG_API phpdbg_input_t *phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ +/* {{{ */ +PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC) { + phpdbg_param_t *top = NULL; + const phpdbg_command_t *handler = NULL; + + if (stack->type != STACK_PARAM) { + asprintf( + why, "The passed argument was not a stack !!"); + return FAILURE; + } + + if (!stack->len) { + asprintf( + why, "The stack contains nothing !!"); + return FAILURE; + } + + top = (phpdbg_param_t*) stack->next; + + switch (top->type) { + case EVAL_PARAM: + return PHPDBG_COMMAND_HANDLER(ev)(top TSRMLS_CC); + + case RUN_PARAM: + return PHPDBG_COMMAND_HANDLER(run)(top TSRMLS_CC); + + case SHELL_PARAM: + return PHPDBG_COMMAND_HANDLER(sh)(top TSRMLS_CC); + + case STR_PARAM: { + handler = phpdbg_stack_resolve( + phpdbg_prompt_commands, NULL, &top, why); + + if (handler) { + if (phpdbg_stack_verify(handler, &top, why TSRMLS_CC) == SUCCESS) { + return handler->handler(top TSRMLS_CC); + } + } + } return FAILURE; + + default: + asprintf( + why, "The first parameter makes no sense !!"); + return FAILURE; + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ { - phpdbg_input_t *buffer = NULL; char *cmd = NULL; -#ifndef HAVE_LIBREADLINE +#if !defined(HAVE_LIBREADLINE) && !defined(HAVE_LIBEDIT) char buf[PHPDBG_MAX_CMD]; #endif + char *buffer = NULL; if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && @@ -477,7 +811,7 @@ disconnect: return NULL; } -#ifndef HAVE_LIBREADLINE +#if !defined(HAVE_LIBREADLINE) && !defined(HAVE_LIBEDIT) if (!(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { if (!phpdbg_write("%s", phpdbg_get_prompt(TSRMLS_C))) { goto disconnect; @@ -513,177 +847,43 @@ readline: } #endif } else cmd = buffered; + + buffer = estrdup(cmd); - /* 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 defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT) if (!buffered && cmd && !(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { free(cmd); } #endif - - return buffer; } - return NULL; -} /* }}} */ + if (buffer && isspace(*buffer)) { + char *trimmed = buffer; + while (isspace(*trimmed)) + trimmed++; -PHPDBG_API void phpdbg_destroy_argv(phpdbg_input_t **argv, int argc TSRMLS_DC) /* {{{ */ -{ - if (argv) { - if (argc) { - int arg; - for (arg=0; arg<argc; arg++) { - phpdbg_destroy_input( - &argv[arg] TSRMLS_CC); - } - } - efree(argv); + trimmed = estrdup(trimmed); + efree(buffer); + buffer = trimmed; } -} /* }}} */ - -PHPDBG_API void phpdbg_destroy_input(phpdbg_input_t **input TSRMLS_DC) /*{{{ */ -{ - if (*input) { - if ((*input)->string) { - efree((*input)->string); + if (buffer && strlen(buffer)) { + if (PHPDBG_G(buffer)) { + efree(PHPDBG_G(buffer)); + } + PHPDBG_G(buffer) = estrdup(buffer); + } else { + if (PHPDBG_G(buffer)) { + buffer = estrdup(PHPDBG_G(buffer)); } - - phpdbg_destroy_argv( - (*input)->argv, (*input)->argc TSRMLS_CC); - - efree(*input); } + + return buffer; } /* }}} */ -PHPDBG_API int phpdbg_do_cmd(const phpdbg_command_t *command, phpdbg_input_t *input TSRMLS_DC) /* {{{ */ +PHPDBG_API void phpdbg_destroy_input(char **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; - phpdbg_command_t *initial_last_cmd; - phpdbg_param_t initial_last_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; arg<input->argc; arg++) { - phpdbg_debug( - "\t#%d: [%s=%zu]", - arg, - input->argv[arg]->string, - input->argv[arg]->length); - } - } - - initial_last_param = PHPDBG_G(lparam); - initial_last_cmd = (phpdbg_command_t *)PHPDBG_G(lcmd); - PHPDBG_G(lparam) = param; - PHPDBG_G(lcmd) = (phpdbg_command_t *)command; - - 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_clear_param(&initial_last_param TSRMLS_CC); - } else if (PHPDBG_G(lcmd) == command && !memcmp(&PHPDBG_G(lparam),& initial_last_param, sizeof(phpdbg_param_t))) { - PHPDBG_G(lparam) = initial_last_param; - PHPDBG_G(lcmd) = initial_last_cmd; - phpdbg_clear_param(¶m TSRMLS_CC); - } - break; - } - command++; - } - } else { - /* this should NEVER happen */ - phpdbg_error( - "No function executed!!"); - } - - return rc; + efree(*input); } /* }}} */ diff --git a/sapi/phpdbg/phpdbg_cmd.h b/sapi/phpdbg/phpdbg_cmd.h index c86f92bb47..571d065f59 100644 --- a/sapi/phpdbg/phpdbg_cmd.h +++ b/sapi/phpdbg/phpdbg_cmd.h @@ -23,8 +23,6 @@ #include "TSRM.h" -typedef struct _phpdbg_command_t phpdbg_command_t; - /* {{{ Command and Parameter */ enum { NO_ARG = 0, @@ -36,24 +34,23 @@ typedef enum { EMPTY_PARAM = 0, ADDR_PARAM, FILE_PARAM, + NUMERIC_FILE_PARAM, METHOD_PARAM, STR_PARAM, NUMERIC_PARAM, NUMERIC_FUNCTION_PARAM, - NUMERIC_METHOD_PARAM + NUMERIC_METHOD_PARAM, + STACK_PARAM, + EVAL_PARAM, + SHELL_PARAM, + COND_PARAM, + OP_PARAM, + ORIG_PARAM, + RUN_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 { +typedef struct _phpdbg_param phpdbg_param_t; +struct _phpdbg_param { phpdbg_param_type type; long num; zend_ulong addr; @@ -67,10 +64,31 @@ typedef struct _phpdbg_param { } method; char *str; size_t len; -} phpdbg_param_t; + phpdbg_param_t *next; + phpdbg_param_t *top; +}; -typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t*, const phpdbg_input_t* TSRMLS_DC); +#define phpdbg_init_param(v, t) do{ \ + (v)->type = (t); \ + (v)->addr = 0; \ + (v)->num = 0; \ + (v)->file.name = NULL; \ + (v)->file.line = 0; \ + (v)->method.class = NULL; \ + (v)->method.name = NULL; \ + (v)->str = NULL; \ + (v)->len = 0; \ + (v)->next = NULL; \ + (v)->top = NULL; \ +} while(0) + +#ifndef YYSTYPE +#define YYSTYPE phpdbg_param_t +#endif + +typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t* TSRMLS_DC); +typedef struct _phpdbg_command_t phpdbg_command_t; struct _phpdbg_command_t { const char *name; /* Command name */ size_t name_len; /* Command name length */ @@ -79,7 +97,8 @@ struct _phpdbg_command_t { char alias; /* Alias */ phpdbg_command_handler_t handler; /* Command handler */ const phpdbg_command_t *subs; /* Sub Commands */ - char arg_type; /* Accept args? */ + char *args; /* Argument Spec */ + const phpdbg_command_t *parent; /* Parent Command */ }; /* }}} */ @@ -95,35 +114,29 @@ typedef struct { } 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 +* 1) the lexer/parser creates a stack of commands and arguments from input +* 2) the commands at the top of the stack are resolved sensibly using aliases, abbreviations and case insensitive matching +* 3) the remaining arguments in the stack are verified (optionally) against the handlers declared argument specification +* 4) the handler is called passing the top of the stack as the only parameter +* 5) the stack is destroyed upon return from the handler */ /* * 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); +PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC); +PHPDBG_API void phpdbg_destroy_input(char** 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) +/** + * Stack Management + */ +PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param); +PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why); +PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC); +PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC); +PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack); /* * Parameter Management @@ -135,28 +148,27 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *, const phpdbg_par 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); +PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg); /** * 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_EXP(name, tip, alias, handler, children, args, parent) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, parent} + +#define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, args) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, NULL} -#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_D(name, tip, alias, children, args) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, args, NULL} -#define PHPDBG_COMMAND(name) int phpdbg_do_##name(const phpdbg_param_t *param, const phpdbg_input_t *input TSRMLS_DC) +#define PHPDBG_COMMAND(name) int phpdbg_do_##name(const phpdbg_param_t *param TSRMLS_DC) -#define PHPDBG_COMMAND_ARGS param, input TSRMLS_CC +#define PHPDBG_COMMAND_ARGS param TSRMLS_CC -#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0'} +#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0', NULL} /* * Default Switch Case diff --git a/sapi/phpdbg/phpdbg_frame.c b/sapi/phpdbg/phpdbg_frame.c index de02addc1b..a235fe8cb0 100644 --- a/sapi/phpdbg/phpdbg_frame.c +++ b/sapi/phpdbg/phpdbg_frame.c @@ -167,7 +167,7 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ zval **tmp; zval **file, **line; HashPosition position; - int i = 1, limit = num; + int i = 0, limit = num; int user_defined; if (limit < 0) { @@ -186,7 +186,7 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ 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)); + phpdbg_write("frame #%d: {main} at %s:%ld", i, Z_STRVAL_PP(file), Z_LVAL_PP(line)); break; } diff --git a/sapi/phpdbg/phpdbg_help.c b/sapi/phpdbg/phpdbg_help.c index d2fea8d7c7..1e58dc69ca 100644 --- a/sapi/phpdbg/phpdbg_help.c +++ b/sapi/phpdbg/phpdbg_help.c @@ -15,589 +15,917 @@ | Authors: Felipe Pena <felipe@php.net> | | Authors: Joe Watkins <joe.watkins@live.co.uk> | | Authors: Bob Weinand <bwoebi@php.net> | + | Authors: Terry Ellison <terry@ellisons.org.uk> | +----------------------------------------------------------------------+ */ #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" +#include "phpdbg_prompt.h" +#include "zend.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -PHPDBG_HELP(exec) /* {{{ */ +/* {{{ Commands Table */ +#define PHPDBG_COMMAND_HELP_D(name, tip, alias, action) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, action, NULL, 0} + +const phpdbg_command_t phpdbg_help_commands[] = { + PHPDBG_COMMAND_HELP_D(aliases, "show alias list", 'a', phpdbg_do_help_aliases), + PHPDBG_COMMAND_HELP_D(options, "command line options", 0, NULL), + PHPDBG_COMMAND_HELP_D(overview, "help overview", 0, NULL), + PHPDBG_COMMAND_HELP_D(phpdbginit, "phpdbginit file format", 0, NULL), + PHPDBG_COMMAND_HELP_D(syntax, "syntax overview", 0, NULL), + PHPDBG_END_COMMAND +}; /* }}} */ + +/* {{{ pretty_print. Formatting escapes and wrapping text in a string before printing it. */ +void pretty_print(char *text TSRMLS_DC) { - 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; -} /* }}} */ + char *new, *p, *q; + + const char *prompt_escape = phpdbg_get_prompt(TSRMLS_C); + unsigned int prompt_escape_len = strlen(prompt_escape); + unsigned int prompt_len = strlen(PHPDBG_G(prompt)[0]); + + const char *bold_on_escape = PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "\033[1m" : ""; + const char *bold_off_escape = PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "\033[0m" : ""; + unsigned int bold_escape_len = strlen(bold_on_escape); + + unsigned int term_width = phpdbg_get_terminal_width(TSRMLS_C); + unsigned int size = 0; + + int in_bold = 0; + + char *last_new_blank = NULL; /* position in new buffer of last blank char */ + unsigned int last_blank_count = 0; /* printable char offset of last blank char */ + unsigned int line_count = 0; /* number printable chars on current line */ + + /* First pass calculates a safe size for the pretty print version */ + for (p = text; *p; p++) { + if (UNEXPECTED(p[0] == '*') && p[1] == '*') { + size += bold_escape_len - 2; + p++; + } else if (UNEXPECTED(p[0] == '$') && p[1] == 'P') { + size += prompt_escape_len - 2; + p++; + } else if (UNEXPECTED(p[0] == '\\')) { + p++; + } + } + size += (p-text)+1; + + new = emalloc(size); + /* + * Second pass substitutes the bold and prompt escape sequences and line wrap + * + * ** toggles bold on and off if PHPDBG_IS_COLOURED flag is set + * $P substitutes the prompt sequence + * Lines are wrapped by replacing the last blank with a CR before <term width> + * characters. (This defaults to 100 if the width can't be detected). In the + * pathelogical case where no blanks are found, then the wrap occurs at the + * first blank. + */ + for (p = text, q = new; *p; p++) { + if (UNEXPECTED(*p == ' ')) { + last_new_blank = q; + last_blank_count = line_count++; + *q++ = ' '; + } else if (UNEXPECTED(*p == '\n')) { + last_new_blank = NULL; + *q++ = *p; + last_blank_count = 0; + line_count = 0; + } else if (UNEXPECTED(p[0] == '*') && p[1] == '*') { + if (bold_escape_len) { + in_bold = !in_bold; + memcpy (q, in_bold ? bold_on_escape : bold_off_escape, bold_escape_len); + q += bold_escape_len; + /* bold on/off has zero print width so line count is unchanged */ + } + p++; + } else if (UNEXPECTED(p[0] == '$') && p[1] == 'P') { + memcpy (q, prompt_escape, prompt_escape_len); + q += prompt_escape_len; + line_count += prompt_len; + p++; + } else if (UNEXPECTED(p[0] == '\\')) { + p++; + *q++ = *p; + line_count++; + } else { + *q++ = *p; + line_count++; + } -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; -} /* }}} */ + if (UNEXPECTED(line_count>=term_width) && last_new_blank) { + *last_new_blank = '\n'; + last_new_blank = NULL; + line_count -= last_blank_count; + last_blank_count = 0; + } + } + *q++ = '\0'; -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; -} /* }}} */ + if ((q-new)>size) { + phpdbg_error("Output overrun of %lu bytes", ((q-new) - size)); + } -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_write("%s\n", new); + efree(new); +} /* }}} */ -PHPDBG_HELP(finish) /* {{{ */ +/* {{{ summary_print. Print a summary line giving, the command, its alias and tip */ +void summary_print(phpdbg_command_t const * const cmd TSRMLS_DC) { - 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) /* {{{ */ + char *summary; + spprintf(&summary, 0, "Command: **%s** Alias: **%c** **%s**\n", cmd->name, cmd->alias, cmd->tip); + pretty_print(summary TSRMLS_CC); + efree(summary); +} + +/* {{{ get_help. Retries and formats text from the phpdbg help text table */ +static char *get_help(const char * const key TSRMLS_DC) { - 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_text_t *p; -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; -} /* }}} */ + /* Note that phpdbg_help_text is not assumed to be collated in key order. This is an + inconvience that means that help can't be logically grouped Not worth + the savings */ -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; + for (p = phpdbg_help_text; p->key; p++) { + if (!strcmp(p->key, key)) { + return p->text; } } - 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; + return ""; /* return empty string to denote no match found */ } /* }}} */ -PHPDBG_HELP(eval) /* {{{ */ +/* {{{ get_command. Return number of matching commands from a command table. + * Unlike the command parser, the help search is sloppy that is partial matches can occur + * * Any single character key is taken as an alias. + * * Other keys are matched again the table on the first len characters. + * * This means that non-unique keys can generate multiple matches. + * * The first matching command is returned as an OUT parameter. * + * The rationale here is to assist users in finding help on commands. So unique matches + * will be used to generate a help message but non-unique one will be used to list alternatives. + */ +static int get_command( + const char *key, size_t len, /* pointer and length of key */ + phpdbg_command_t const **command, /* address of first matching command */ + phpdbg_command_t const * commands /* command table to be scanned */ + TSRMLS_DC) { - 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 occurrence 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); + const phpdbg_command_t *c; + unsigned int num_matches = 0; + + if (len == 1) { + for (c=commands; c->name; c++) { + if (c->alias == key[0]) { + num_matches++; + if ( num_matches == 1 && command) { + *command = c; + } } - ++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); + } else { + for (c=commands; c->name; c++) { + if (!strncmp(c->name, key, len)) { + ++num_matches; + if ( num_matches == 1 && command) { + *command = c; + } } - ++info_command; } } - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ + return num_matches; -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_COMMAND(help) /* {{{ */ { - 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_command_t const *cmd; + int n; -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; -} /* }}} */ + if (!param || param->type == EMPTY_PARAM) { + pretty_print(get_help("overview!" TSRMLS_CC) TSRMLS_CC); + 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); + if (param && param->type == STR_PARAM) { + n = get_command(param->str, param->len, &cmd, phpdbg_prompt_commands TSRMLS_CC); + + if (n==1) { + summary_print(cmd TSRMLS_CC); + pretty_print(get_help(cmd->name TSRMLS_CC) TSRMLS_CC); + return SUCCESS; + + } else if (n>1) { + if (param->len > 1) { + for (cmd=phpdbg_prompt_commands; cmd->name; cmd++) { + if (!strncmp(cmd->name, param->str, param->len)) { + summary_print(cmd TSRMLS_CC); + } + } + pretty_print(get_help("duplicate!" TSRMLS_CC) TSRMLS_CC); + return SUCCESS; } else { - phpdbg_writeln("\t[ ]\t%s\t\t%s", list_command->name, list_command->tip); + phpdbg_error("Internal help error, non-unique alias \"%c\"", param->str[0]); + return FAILURE; + } + + } else { /* no prompt command found so try help topic */ + n = get_command( param->str, param->len, &cmd, phpdbg_help_commands TSRMLS_CC); + + if (n>0) { + if (cmd->alias == 'a') { /* help aliases executes a canned routine */ + return cmd->handler(param TSRMLS_CC); + } else { + pretty_print(get_help(cmd->name TSRMLS_CC) TSRMLS_CC); + return SUCCESS; + } } - ++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; + return FAILURE; + } /* }}} */ -PHPDBG_HELP(set) /* {{{ */ +PHPDBG_HELP(aliases) /* {{{ */ { - 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); + const phpdbg_command_t *c, *c_sub; + int len; + + /* Print out aliases for all commands except help as this one comes last */ + phpdbg_writeln("Below are the aliased, short versions of all supported commands"); + for(c = phpdbg_prompt_commands; c->name; c++) { + if (c->alias && c->alias != 'h') { + phpdbg_writeln(" %c %-20s %s", c->alias, c->name, c->tip); + if (c->subs) { + len = 20 - 1 - c->name_len; + for(c_sub = c->subs; c_sub->alias; c_sub++) { + if (c_sub->alias) { + phpdbg_writeln(" %c %c %s %-*s %s", + c->alias, c_sub->alias, (char *)c->name, len, c_sub->name, c_sub->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; + + /* Print out aliases for help as this one comes last, with the added text on how aliases are used */ + get_command("h", 1, &c, phpdbg_prompt_commands TSRMLS_CC); + phpdbg_writeln(" %c %-20s %s\n", c->alias, c->name, c->tip); + + len = 20 - 1 - c->name_len; + for(c_sub = c->subs; c_sub->alias; c_sub++) { + if (c_sub->alias) { + phpdbg_writeln(" %c %c %s %-*s %s", + c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip); } } - phpdbg_writeln("The <element> for set color can be \"prompt\", \"notice\", or \"error\""); -#endif - phpdbg_help_footer(); + + pretty_print(get_help("aliases!" TSRMLS_CC) TSRMLS_CC); 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; -} /* }}} */ +/* {{{ Help Text Table + * Contains help text entries keyed by a lowercase ascii key. + * Text is in ascii and enriched by a simple markup: + * ** toggles bold font emphasis. + * $P insert an bold phpdbg> prompt. + * \ escapes the following character. Note that this is itself escaped inside string + * constants so \\\\ is required to output a single \ e.g. as in namespace names. + * + * Text will be wrapped according to the STDOUT terminal width, so paragraphs are + * flowed using the C stringizing and the CR definition. Also note that entries + * are collated in alphabetic order on key. + * + * Also note the convention that help text not directly referenceable as a help param + * has a key ending in ! + */ +#define CR "\n" +phpdbg_help_text_t phpdbg_help_text[] = { + +/******************************** General Help Topics ********************************/ +{"overview!", CR +"**phpdbg** is a lightweight, powerful and easy to use debugging platform for PHP5.4+" CR +"It supports the following commands:" CR CR + +"**Information**" CR +" **list** list PHP source" CR +" **info** displays information on the debug session" CR +" **print** show opcodes" CR +" **frame** select a stack frame and print a stack frame summary" CR +" **back** shows the current backtrace" CR +" **help** provide help on a topic" CR CR + +"**Starting and Stopping Execution**" CR +" **exec** set execution context" CR +" **run** attempt execution" CR +" **step** continue execution until other line is reached" CR +" **continue** continue execution" CR +" **until** continue execution up to the given location" CR +" **finish** continue up to end of the current execution frame" CR +" **leave** continue up to end of the current execution frame and halt after the calling instruction" CR +" **break** set a breakpoint at the specified target" CR +" **watch** set a watchpoint on $variable" CR +" **clear** clear one or all breakpoints" CR +" **clean** clean the execution environment" CR CR + +"**Miscellaneous**" CR +" **set** set the phpdbg configuration" CR +" **source** execute a phpdbginit script" CR +" **register** register a phpdbginit function as a command alias" CR +" **sh** shell a command" CR +" **ev** evaluate some code" CR +" **quit** exit phpdbg" CR CR + +"Type **help <command>** or (**help alias**) to get detailed help on any of the above commands, " +"for example **help list** or **h l**. Note that help will also match partial commands if unique " +"(and list out options if not unique), so **help clea** will give help on the **clean** command, " +"but **help cl** will list the summary for **clean** and **clear**." CR CR + +"Type **help aliases** to show a full alias list, including any registered phpdginit functions" CR +"Type **help syntax** for a general introduction to the command syntax." CR +"Type **help options** for a list of phpdbg command line options." CR +"Type **help phpdbginit** to show how to customise the debugger environment." +}, +{"options", CR +"Below are the command line options supported by phpdbg" CR CR + /* note the extra 4 space index in because of the extra **** */ +"**Command Line Options and Flags**" CR +" **Option** **Example Argument** **Description**" CR +" **-c** **-c**/my/php.ini Set php.ini file to load" CR +" **-d** **-d**memory_limit=4G Set a php.ini directive" CR +" **-n** Disable default php.ini" CR +" **-q** Supress welcome banner" CR +" **-v** Enable oplog output" CR +" **-s** Enable stepping" CR +" **-b** Disable colour" CR +" **-i** **-i**my.init Set .phpdbginit file" CR +" **-I** Ignore default .phpdbginit" CR +" **-O** **-O**my.oplog Sets oplog output file" CR +" **-r** Run execution context" CR +" **-rr** Run execution context and quit after execution" CR +" **-E** Enable step through eval, careful!" CR +" **-S** **-S**cli Override SAPI name, careful!" CR +" **-l** **-l**4000 Setup remote console ports" CR +" **-a** **-a**192.168.0.3 Setup remote console bind address" CR +" **-V** Print version number" CR +" **--** **--** arg1 arg2 Use to delimit phpdbg arguments and php $argv; append any $argv " +"argument after it" CR CR + +"**Remote Console Mode**" CR CR + +"This mode is enabled by specifying the **-a** option. Phpdbg will bind only to the loopback " +"interface by default, and this can only be overridden by explicitly setting the remote console " +"bind address using the **-a** option. If **-a** is specied without an argument, then phpdbg " +"will bind to all available interfaces. You should be aware of the security implications of " +"doing this, so measures should be taken to secure this service if bound to a publicly accessible " +"interface/port." CR CR + +"Specify both stdin and stdout with -lstdin/stdout; by default stdout is stdin * 2." +}, + +{"phpdbginit", CR +"Phpdgb uses an debugger script file to initialize the debugger context. By default, phpdbg looks " +"for the file named **.phpdbginit** in the current working directory. This location can be " +"overridden on the command line using the **-i** switch (see **help options** for a more " +"details)." CR CR + +"Debugger scripts can also be executed using the **source** command." CR CR + +"A script file can contain a sequence of valid debugger commands, comments and embedded PHP " +"code. " CR CR + +"Comment lines are prefixed by the **#** character. Note that comments are only allowed in script " +"files and not in interactive sessions." CR CR + +"PHP code is delimited by the start and end escape tags **<:** and **:>**. PHP code can be used " +"to define application context for a debugging session and also to extend the debugger by defining " +"and **register** PHP functions as new commands." CR CR + +"Also note that executing a **clear** command will cause the current **phpdbginit** to be reparsed " +"/ reloaded." +}, + +{"syntax", CR +"Commands start with a keyword, and some (**break**, " +"**info**, **set**, **print** and **list**) may include a subcommand keyword. All keywords are " +"lower case but also have a single letter alias that may be used as an alternative to typing in the" +"keyword in full. Note some aliases are uppercase, and that keywords cannot be abbreviated other " +"than by substitution by the alias." CR CR + +"Some commands take an argument. Arguments are typed according to their format:" CR +" * **omitted**" CR +" * **address** **0x** followed by a hex string" CR +" * **number** an optionally signed number" CR +" * **method** a valid **Class::methodName** expression" CR +" * **func#op** a valid **Function name** follow by # and an integer" CR +" * **method#op** a valid **Class::methodName** follow by # and an integer" CR +" * **string** a general string" CR +" * **function** a valid **Function name**" CR +" * **file:line** a valid **filename** follow by : and an integer" CR CR + +"In some cases the type of the argument enables the second keyword to be omitted." CR CR + +"Type **help** for an overview of all commands and type **help <command>** to get detailed help " +"on any specific command." CR CR + +"**Valid Examples**" CR CR + +" $P quit" CR +" $P q" CR +" Quit the debugger" CR CR + +" $P ev $total[2]" CR +" Evaluate and print the variable $total[2] in the current stack frame" CR +" " CR +" $P break 200" CR +" $P b my_source.php:200" CR +" Break at line 200 in the current source and in file **my_source.php**. " CR CR + +" $P b @ ClassX::get_args if $arg[0] == \"fred\"" CR +" $P b ~ 3" CR +" Break at ClassX::get_args() if $arg[0] == \"fred\" and delete breakpoint 3" CR CR + +"**Examples of invalid commands**" CR + +" $P #This is a comment" CR +" Comments introduced by the **#** character are only allowed in **phpdbginit** script files." +}, + +/******************************** Help Codicils ********************************/ +{"aliases!", CR +"Note that aliases can be used for either command or sub-command keywords or both, so **info b** " +"is a synomyn for **info break** and **l func** for **list func**, etc." CR CR + +"Note that help will also accept any alias as a parameter and provide help on that command, for example **h p** will provide help on the print command." +}, + +{"duplicate!", CR +"Parameter is not unique. For detailed help select help on one of the above commands." +}, + +/******************************** Help on Commands ********************************/ +{"back", +"Provide a formatted backtrace using the standard debug_backtrace() functionality. An optional " +"unsigned integer argument specifying the maximum number of frames to be traced; if omitted then " +"a complete backtrace is given." CR CR + +"**Examples**" CR CR +" $P back 5" CR +" $P t " CR +" " CR +"A backtrace can be executed at any time during execution." +}, + +{"break", +"Breakpoints can be set at a range of targets within the execution environment. Execution will " +"be paused if the program flow hits a breakpoint. The break target can be one of the following " +"types:" CR CR + +" **Target** **Alias** **Purpose**" CR +" **at** **A** specify breakpoint by location and condition" CR +" **del** **d** delete breakpoint by breakpoint identifier number" CR CR + +"**Break at** takes two arguments. The first is any valid target. The second " +"is a valid PHP expression which will trigger the break in " +"execution, if evaluated as true in a boolean context at the specified target." CR CR -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; -} /* }}} */ +"Note that breakpoints can also be disabled and re-enabled by the **set break** command." CR CR + +"**Examples**" CR CR +" $P break test.php:100" CR +" $P b test.php:100" CR +" Break execution at line 100 of test.php" CR CR + +" $P break 200" CR +" $P b 200" CR +" Break execution at line 200 of the currently PHP script file" CR CR + +" $P break \\\\mynamespace\\\\my_function" CR +" $P b \\\\mynamespace\\\\my_function" CR +" Break execution on entry to \\\\mynamespace\\\\my_function" CR CR + +" $P break classX::method" CR +" $P b classX::method" CR +" Break execution on entry to classX::method" CR CR + +" $P break 0x7ff68f570e08" CR +" $P b 0x7ff68f570e08" CR +" Break at the opline at the address 0x7ff68f570e08" CR CR -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; -} /* }}} */ +" $P break my_function#14" CR +" $P b my_function#14" CR +" Break at the opline #14 of the function my_function" CR CR -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\tSuppress 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; -} /* }}} */ +" $P break \\\\my\\\\class::method#2" CR +" $P b \\\\my\\\\class::method#2" CR +" Break at the opline #2 of the method \\\\my\\\\class::method" CR CR + +" $P break test.php:#3" CR +" $P b test.php:#3" CR +" Break at opline #3 in test.php" CR CR + +" $P break if $cnt > 10" CR +" $P b if $cnt > 10" CR +" Break when the condition ($cnt > 10) evaluates to true" CR CR + +" $P break at phpdbg::isGreat if $opt == 'S'" CR +" $P break @ phpdbg::isGreat if $opt == 'S'" CR +" Break at any opcode in phpdbg::isGreat when the condition ($opt == 'S') is true" CR CR + +" $P break at test.php:20 if !isset($x)" CR +" Break at every opcode on line 20 of test.php when the condition evaluates to true" CR CR + +" $P break ZEND_ADD" CR +" $P b ZEND_ADD" CR +" Break on any occurence of the opcode ZEND_ADD" CR CR + +" $P break del 2" CR +" $P b ~ 2" CR +" Remove breakpoint 2" CR CR + +"Note: Conditional breaks are costly in terms of runtime overhead. Use them only when required " +"as they significantly slow execution." CR CR + +"Note: An address is only valid for the current compilation." +}, + +{"clean", +"Classes, constants or functions can only be declared once in PHP. You may experience errors " +"during a debug session if you attempt to recompile a PHP source. The clean command clears " +"the Zend runtime tables which holds the sets of compiled classes, constants and functions, " +"releasing any associated storage back into the storage pool. This enables recompilation to " +"take place." CR CR + +"Note that you cannot selectively trim any of these resource pools. You can only do a complete " +"clean." +}, + +{"clear", +"Clearing breakpoints means you can once again run code without interruption." CR CR + +"Note: use break delete N to clear a specific breakpoint." CR CR + +"Note: if all breakpoints are cleared, then the PHP script will run until normal completion." +}, + +{"ev", +"The **ev** command takes a string expression which it evaluates and then displays. It " +"evaluates in the context of the lowest (that is the executing) frame, unless this has first " +"been explicitly changed by issuing a **frame** command. " CR CR + +"**Examples**" CR CR +" $P ev $variable" CR +" Will print_r($variable) on the console, if it is defined" CR CR + +" $P ev $variable = \"Hello phpdbg :)\"" CR +" Will set $variable in the current scope" CR CR + +"Note that **ev** allows any valid PHP expression including assignments, function calls and " +"other write statements. This enables you to change the environment during execution, so care " +"is needed here. You can even call PHP functions which have breakpoints defined. " CR CR + +"Note: **ev** will always show the result, so do not prefix the code with **return**" +}, + +{"exec", +"The **exec** command sets the execution context, that is the script to be executed. The " +"execution context must be defined either by executing the **exec** command or by using the " +"**-e** command line option." CR CR + +"Note that the **exec** command also can be used to replace a previously defined execution " +"context." CR CR + +"**Examples**" CR CR + +" $P exec /tmp/script.php" CR +" $P e /tmp/script.php" CR +" Set the execution context to **/tmp/script.php**" +}, + +//*********** Does F skip any breakpoints lower stack frames or only the current?? +{"finish", +"The **finish** command causes control to be passed back to the vm, continuing execution. Any " +"breakpoints that are encountered within the current stack frame will be skipped. Execution " +"will then continue until the next breakpoint after leaving the stack frame or until " +"completion of the script" CR CR + +"Note when **step**ping is enabled, any opcode steps within the current stack frame are also " +"skipped. "CR CR + +"Note **finish** will trigger a \"not executing\" error if not executing." +}, + +{"frame", +"The **frame** takes an optional integer argument. If omitted, then the current frame is displayed " +"If specified then the current scope is set to the corresponding frame listed in a **back** trace. " "This can be used to allowing access to the variables in a higher stack frame than that currently " +"being executed." CR CR + +"**Examples**" CR CR +" $P frame 2" CR +" $P ev $count" CR +" Go to frame 2 and print out variable **$count** in that frame" CR CR + +"Note that this frame scope is discarded when execution continues, with the execution frame " +"then reset to the lowest executiong frame." +}, + +{"info", +"**info** commands provide quick access to various types of information about the PHP environment" CR +"Specific info commands are show below:" CR CR + +" **Target** **Alias** **Purpose**" CR +" **break** **b** show current breakpoints" CR +" **files** **F** show included files" CR +" **classes** **c** show loaded classes" CR +" **funcs** **f** show loaded classes" CR +" **error** **e** show last error" CR +" **vars** **v** show active variables" CR +" **literal** **l** show active literal constants" CR +" **memory** **m** show memory manager stats" +}, + +// ******** same issue about breakpoints in called frames +{"leave", +"The **leave** command causes control to be passed back to the vm, continuing execution. Any " +"breakpoints that are encountered within the current stack frame will be skipped. In effect a " +"temporary breakpoint is associated with any return opcode, so that a break in execution occurs " +"before leaving the current stack frame. This allows inspection / modification of any frame " +"variables including the return value before it is returned" CR CR + +"**Examples**" CR CR + +" $P leave" CR +" $P L" CR CR + +"Note when **step**ping is enabled, any opcode steps within the current stack frame are also " +"skipped. "CR CR + +"Note **leave** will trigger a \"not executing\" error if not executing." +}, + +{"list", +"The list command displays source code for the given argument. The target type is specficied by " +"a second subcommand keyword:" CR CR + +" **Type** **Alias** **Purpose**" CR +" **lines** **l** List N lines from the current execution point" CR +" **func** **f** List the complete source for a specified function" CR +" **method** **m** List the complete source for a specified class::method" CR +" **class** **c** List the complete source for a specified class" CR CR + +"Note that the context of **lines**, **func** and **method** can be determined by parsing the " +"argument, so these subcommands are optional. However, you must specify the **class** keyword " +"to list off a class." CR CR + +"**Examples**" CR CR +" $P list 2" CR +" $P l l 2" CR +" List the next 2 lines from the current file" CR CR + +" $P list my_function" CR +" $P l f my_function" CR +" List the source of the function **my_function**" CR CR + +//************ ???? +" $P list func .mine" CR +" $P l f .mine" CR +" List the source of the method **mine** from the active class in scope" CR CR + +" $P list m my::method" CR +" $P l my::method" CR +" List the source of **my::method**" CR CR + +" $P list c myClass" CR +" $P l c myClass" CR +" List the source of **myClass**" CR CR + +"Note that functions and classes can only be listed if the corresponding classes and functions " +"table in the Zend executor has a corresponding entry. You can use the compile command to " +"populate these tables for a given execution context." +}, + +{"continue", +"Continue with execution after hitting a break or watchpoint" CR CR + +"**Examples**" CR CR +" $P continue" CR +" $P c" CR +" Continue executing until the next break or watchpoint" CR CR + +"Note **continue** will trigger a \"not running\" error if not executing." +}, + +{"print", +"By default, print will show information about the current execution context." CR +"Other printing commands give access to instruction information." CR +"Specific printers loaded are show below:" CR CR + +" **Type** **Alias** **Purpose**" CR +" **exec** **e** print out the instructions in the execution context" CR +" **opline** **o** print out the instruction in the current opline" CR +" **class** **c** print out the instructions in the specified class" CR +" **method** **m** print out the instructions in the specified method" CR +" **func** **f** print out the instructions in the specified function" CR +" **stack** **s** print out the instructions in the current stack" CR CR + +"**Examples**" CR CR +" $P print class \\\\my\\\\class" CR +" $P p c \\\\my\\\\class" CR +" Print the instructions for the methods in \\\\my\\\\class" CR CR + +" $P print method \\\\my\\\\class::method" CR +" $P p m \\\\my\\\\class::method" CR +" Print the instructions for \\\\my\\\\class::method" CR CR + +" $P print func .getSomething" CR +" $P p f .getSomething" CR +//************* Check this local method scope +" Print the instructions for ::getSomething in the active scope" CR CR + +" $P print func my_function" CR +" $P p f my_function" CR +" Print the instructions for the global function my_function" CR CR + +" $P print opline" CR +" $P p o" CR +" Print the instruction for the current opline" CR CR + +" $P print exec" CR +" $P p e" CR +" Print the instructions for the execution context" CR CR + +" $P print stack" CR +" $P p s" CR +" Print the instructions for the current stack" +}, + +{"register", +//******* Needs a general explanation of the how registered functions work +"Register any global function for use as a command in phpdbg console" CR CR + +"**Examples**" CR CR +" $P register scandir" CR +" $P R scandir" CR +" Will register the scandir function for use in phpdbg" CR CR + +"Note: arguments passed as strings, return (if present) print_r'd on console" +}, + +{"run", +"Enter the vm, startinging execution. Execution will then continue until the next breakpoint " +"or completion of the script. Add parameters you want to use as $argv" +"**Examples**" CR CR +" $P run" CR +" $P r" CR +" Will cause execution of the context, if it is set" CR CR +" $P r test" CR +" Will execute with $argv[1] == \"test\"" CR CR + +"Note that the execution context must be set. If not previously compiled, then the script will " +"be compiled before execution." CR CR + +"Note that attempting to run a script that is already executing will result in an \"execution " +"in progress\" error." +}, + +{"set", +"The **set** command is used to configure how phpdbg looks and behaves. Specific set commands " +"are as follows:" CR CR + +" **Type** **Alias** **Purpose**" CR +" **prompt** **p** set the prompt" CR +" **color** **c** set color <element> <color>" CR +" **colors** **C** set colors [<on|off>]" CR +" **oplog** **O** set oplog [output]" CR +" **break** **b** set break **id** <on|off>" CR +" **breaks** **B** set breaks [<on|off>]" CR +" **quiet** **q** set quiet [<on|off>]" CR +" **stepping** **s** set stepping [<opcode|line>]" CR +" **refcount** **r** set refcount [<on|off>] " CR CR + +"Valid colors are **none**, **white**, **red**, **green**, **yellow**, **blue**, **purple**, " +"**cyan** and **black**. All colours except **none** can be followed by an optional " +"**-bold** or **-underline** qualifier." CR CR + +"Color elements can be one of **prompt**, **notice**, or **error**." CR CR + +"**Examples**" CR CR +" $P S C on" CR +" Set colors on" CR CR + +" $P set p >" CR +" $P set color prompt white-bold" CR +" Set the prompt to a bold >" CR CR + +" $P S c error red-bold" CR +" Use red bold for errors" CR CR + +" $P S refcount on" CR +" Enable refcount display when hitting watchpoints" CR CR + +" $P S b 4 off" CR +" Temporarily disable breakpoint 4. This can be subsequently reenabled by a **s b 4 on**." CR +//*********** check oplog syntax +}, + +{"sh", +"Direct access to shell commands saves having to switch windows/consoles" CR CR + +"**Examples**" CR CR +" $P sh ls /usr/src/php-src" CR +" Will execute ls /usr/src/php-src, displaying the output in the console" +//*********** what does this mean????Note: read only commands please! +}, + +{"source", +"Sourcing a **phpdbginit** script during your debugging session might save some time." CR CR + +"**Examples**" CR CR + +" $P source /my/init" CR +" $P < /my/init" CR +" Will execute the phpdbginit file at /my/init" CR CR +}, + +{"export", +"Exporting breakpoints allows you to share, and or save your current debugging session" CR CR + +"**Examples**" CR CR + +" $P export /my/exports" CR +" $P > /my/exports" CR +" Will export all breakpoints to /my/exports" CR CR +}, + +{"step", +"Execute opcodes until next line" CR CR + +"**Examples**" CR CR + +" $P s" CR +" Will continue and break again in the next encountered line" CR CR +}, + +{"until", +"The **until** command causes control to be passed back to the vm, continuing execution. Any " +"breakpoints that are encountered before the next source line will be skipped. Execution " +"will then continue until the next breakpoint or completion of the script" CR CR + +"Note when **step**ping is enabled, any opcode steps within the current line are also skipped. "CR CR + +"Note that if the next line is **not** executed then **all** subsequent breakpoints will be " +"skipped. " CR CR + +"Note **until** will trigger a \"not executing\" error if not executing." + +}, +{"watch", +"Sets watchpoints on variables as long as they are defined" CR +"Passing no parameter to **watch**, lists all actually active watchpoints" CR CR + +"**Format for $variable**" CR CR +" **$var** Variable $var" CR +" **$var[]** All array elements of $var" CR +" **$var->** All properties of $var" CR +" **$var->a** Property $var->a" CR +" **$var[b]** Array element with key b in array $var" CR CR + +"Subcommands of **watch**:" CR CR + +" **Type** **Alias** **Purpose**" CR +" **array** **a** Sets watchpoint on array/object to observe if an entry is added or removed" CR +" **recursive** **r** Watches variable recursively and automatically adds watchpoints if some entry is added to an array/object" CR +" **delete** **d** Removes watchpoint" CR CR + +"Note when **recursive** watchpoints are removed, watchpoints on all the children are removed too" CR CR + +"**Examples**" CR CR +" $P watch" CR +" List currently active watchpoints" CR CR + +" $P watch $array" CR +" $P w $array" CR +" Set watchpoint on $array" CR CR + +" $P watch recursive $obj->" CR +" $P w r $obj->" CR +" Set recursive watchpoint on $obj->" CR CR + +" $P watch delete $obj->a" CR +" $P w d $obj->a" CR +" Remove watchpoint $obj->a" CR CR + +"Technical note: If using this feature with a debugger, you will get many segmentation faults, each time when a memory page containing a watched address is hit." CR +" You then you can continue, phpdbg will remove the write protection, so that the program can continue." CR +" If phpdbg could not handle that segfault, the same segfault is triggered again and this time phpdbg will abort." +}, +{NULL, NULL /* end of table marker */} +}; /* }}} */ diff --git a/sapi/phpdbg/phpdbg_help.h b/sapi/phpdbg/phpdbg_help.h index 319142cb5b..16a1e771e3 100644 --- a/sapi/phpdbg/phpdbg_help.h +++ b/sapi/phpdbg/phpdbg_help.h @@ -30,63 +30,19 @@ /** * 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); +PHPDBG_HELP(aliases); -/** - * 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 -}; +extern const phpdbg_command_t phpdbg_help_commands[]; #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); +typedef struct _phpdbg_help_text_t { + char *key; + char *text; +} phpdbg_help_text_t; + +extern phpdbg_help_text_t phpdbg_help_text[]; #endif /* PHPDBG_HELP_H */ diff --git a/sapi/phpdbg/phpdbg_info.c b/sapi/phpdbg/phpdbg_info.c index 0f4233bf30..97f88bfa1e 100644 --- a/sapi/phpdbg/phpdbg_info.c +++ b/sapi/phpdbg/phpdbg_info.c @@ -23,9 +23,25 @@ #include "phpdbg_utils.h" #include "phpdbg_info.h" #include "phpdbg_bp.h" +#include "phpdbg_prompt.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +#define PHPDBG_INFO_COMMAND_D(f, h, a, m, l, s) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[14]) + +const phpdbg_command_t phpdbg_info_commands[] = { + PHPDBG_INFO_COMMAND_D(break, "show breakpoints", 'b', info_break, NULL, 0), + PHPDBG_INFO_COMMAND_D(files, "show included files", 'F', info_files, NULL, 0), + PHPDBG_INFO_COMMAND_D(classes, "show loaded classes", 'c', info_classes, NULL, 0), + PHPDBG_INFO_COMMAND_D(funcs, "show loaded classes", 'f', info_funcs, NULL, 0), + PHPDBG_INFO_COMMAND_D(error, "show last error", 'e', info_error, NULL, 0), + PHPDBG_INFO_COMMAND_D(vars, "show active variables", 'v', info_vars, NULL, 0), + PHPDBG_INFO_COMMAND_D(literal, "show active literal constants", 'l', info_literal, NULL, 0), + PHPDBG_INFO_COMMAND_D(memory, "show memory manager stats", 'm', info_memory, NULL, 0), + PHPDBG_END_COMMAND +}; + PHPDBG_INFO(break) /* {{{ */ { phpdbg_print_breakpoints(PHPDBG_BREAK_FILE TSRMLS_CC); diff --git a/sapi/phpdbg/phpdbg_info.h b/sapi/phpdbg/phpdbg_info.h index a6b4e3719f..c36e6bebd6 100644 --- a/sapi/phpdbg/phpdbg_info.h +++ b/sapi/phpdbg/phpdbg_info.h @@ -34,16 +34,6 @@ 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 -}; +extern const phpdbg_command_t phpdbg_info_commands[]; #endif /* PHPDBG_INFO_H */ diff --git a/sapi/phpdbg/phpdbg_lexer.c b/sapi/phpdbg/phpdbg_lexer.c new file mode 100644 index 0000000000..3092dc396d --- /dev/null +++ b/sapi/phpdbg/phpdbg_lexer.c @@ -0,0 +1,1143 @@ +/* Generated by re2c 0.13.5 */ +#line 1 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +/* + * phpdbg_lexer.l + */ + +#include "phpdbg.h" +#include "phpdbg_cmd.h" + +#include "phpdbg_parser.h" + +#define LEX(v) (PHPDBG_G(lexer).v) + +#define YYCTYPE unsigned char +#define YYSETCONDITION(x) LEX(state) = x; +#define YYGETCONDITION() LEX(state) +#define YYCURSOR LEX(cursor) +#define YYMARKER LEX(marker) +#define yyleng LEX(len) +#define yytext ((char*) LEX(text)) +#undef YYDEBUG +#define YYDEBUG(a, b) +#define YYFILL(n) + +#define NORMAL 0 +#define RAW 1 +#define INITIAL 2 + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +void phpdbg_init_lexer (phpdbg_param_t *stack, char *input TSRMLS_DC) { + PHPDBG_G(parser_stack) = stack; + + YYSETCONDITION(INITIAL); + + LEX(text) = YYCURSOR = (unsigned char *) input; + LEX(len) = strlen(input); +} + +int phpdbg_lex (phpdbg_param_t* yylval) { + TSRMLS_FETCH(); /* Slow, but this is not a major problem here. TODO: Use TSRMLS_DC */ + +restart: + LEX(text) = YYCURSOR; + + +#line 48 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + if (YYGETCONDITION() < 1) { + goto yyc_NORMAL; + } else { + if (YYGETCONDITION() < 2) { + goto yyc_RAW; + } else { + goto yyc_INITIAL; + } + } +/* *********************************** */ +yyc_INITIAL: + { + static const unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 128, 0, 0, 128, 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(0, *YYCURSOR); + YYFILL(4); + yych = *YYCURSOR; + if (yych <= 'D') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy6; + if (yych <= 0x08) goto yy11; + if (yych >= '\n') goto yy4; + } else { + if (yych <= '\r') { + if (yych <= '\f') goto yy11; + } else { + if (yych != ' ') goto yy11; + } + } + } else { + if (yych <= 'd') { + if (yych <= 'Q') { + if (yych <= 'E') goto yy7; + goto yy11; + } else { + if (yych <= 'R') goto yy10; + if (yych <= 'S') goto yy8; + goto yy11; + } + } else { + if (yych <= 'q') { + if (yych <= 'e') goto yy7; + goto yy11; + } else { + if (yych <= 'r') goto yy9; + if (yych <= 's') goto yy8; + goto yy11; + } + } + } + YYDEBUG(2, *YYCURSOR); + ++YYCURSOR; + if ((yych = *YYCURSOR) <= '\f') { + if (yych <= 0x08) goto yy3; + if (yych <= '\n') goto yy26; + } else { + if (yych <= '\r') goto yy26; + if (yych == ' ') goto yy26; + } +yy3: + YYDEBUG(3, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 161 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + YYSETCONDITION(NORMAL); + + YYCURSOR = LEX(text); + goto restart; +} +#line 154 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy4: + YYDEBUG(4, *YYCURSOR); + ++YYCURSOR; + if ((yych = *YYCURSOR) <= '\f') { + if (yych <= 0x08) goto yy5; + if (yych <= '\n') goto yy26; + } else { + if (yych <= '\r') goto yy26; + if (yych == ' ') goto yy26; + } +yy5: + YYDEBUG(5, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + return 0; +} +#line 172 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy6: + YYDEBUG(6, *YYCURSOR); + yych = *++YYCURSOR; + goto yy3; +yy7: + YYDEBUG(7, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'V') goto yy22; + if (yych == 'v') goto yy22; + goto yy3; +yy8: + YYDEBUG(8, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'H') goto yy18; + if (yych == 'h') goto yy18; + goto yy3; +yy9: + YYDEBUG(9, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy15; + } + if (yych == 'U') goto yy12; + if (yych == 'u') goto yy12; + goto yy3; +yy10: + YYDEBUG(10, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'U') goto yy12; + if (yych == 'u') goto yy12; + goto yy3; +yy11: + YYDEBUG(11, *YYCURSOR); + yych = *++YYCURSOR; + goto yy3; +yy12: + YYDEBUG(12, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'N') goto yy14; + if (yych == 'n') goto yy14; +yy13: + YYDEBUG(13, *YYCURSOR); + YYCURSOR = YYMARKER; + goto yy3; +yy14: + YYDEBUG(14, *YYCURSOR); + yych = *++YYCURSOR; + if (yybm[0+yych] & 128) { + goto yy15; + } + goto yy13; +yy15: + YYDEBUG(15, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(16, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy15; + } + YYDEBUG(17, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 155 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + YYSETCONDITION(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_RUN; +} +#line 245 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy18: + YYDEBUG(18, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\f') { + if (yych <= 0x08) goto yy13; + if (yych >= '\v') goto yy13; + } else { + if (yych <= '\r') goto yy19; + if (yych != ' ') goto yy13; + } +yy19: + YYDEBUG(19, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(20, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy21; + if (yych <= '\n') goto yy19; + } else { + if (yych <= '\r') goto yy19; + if (yych == ' ') goto yy19; + } +yy21: + YYDEBUG(21, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 150 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + YYSETCONDITION(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_SHELL; +} +#line 278 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy22: + YYDEBUG(22, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\f') { + if (yych <= 0x08) goto yy13; + if (yych >= '\v') goto yy13; + } else { + if (yych <= '\r') goto yy23; + if (yych != ' ') goto yy13; + } +yy23: + YYDEBUG(23, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(24, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy25; + if (yych <= '\n') goto yy23; + } else { + if (yych <= '\r') goto yy23; + if (yych == ' ') goto yy23; + } +yy25: + YYDEBUG(25, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 145 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + YYSETCONDITION(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_EVAL; +} +#line 311 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy26: + YYDEBUG(26, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(27, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy28; + if (yych <= '\n') goto yy26; + } else { + if (yych <= '\r') goto yy26; + if (yych == ' ') goto yy26; + } +yy28: + YYDEBUG(28, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + /* ignore whitespace */ + + goto restart; +} +#line 334 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" + } +/* *********************************** */ +yyc_NORMAL: + { + static const unsigned char yybm[] = { + 0, 16, 16, 16, 16, 16, 16, 16, + 16, 8, 8, 16, 16, 8, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 16, 0, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 48, 16, + 176, 176, 176, 176, 176, 176, 176, 176, + 176, 176, 0, 16, 16, 16, 16, 16, + 16, 208, 208, 208, 208, 208, 208, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 16, 16, 16, 16, 16, + 16, 208, 208, 208, 208, 208, 208, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + }; + YYDEBUG(29, *YYCURSOR); + YYFILL(11); + yych = *YYCURSOR; + YYDEBUG(-1, yych); + switch (yych) { + case 0x00: goto yy36; + case '\t': + case '\r': + case ' ': goto yy31; + case '\n': goto yy34; + case '#': goto yy55; + case '-': goto yy41; + case '.': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy42; + case '0': goto yy45; + case ':': goto yy57; + case 'D': + case 'd': goto yy46; + case 'E': + case 'e': goto yy47; + case 'F': + case 'f': goto yy48; + case 'I': + case 'i': goto yy37; + case 'N': + case 'n': goto yy49; + case 'O': + case 'o': goto yy50; + case 'T': + case 't': goto yy51; + case 'Y': + case 'y': goto yy52; + case 'Z': goto yy53; + case 'z': goto yy54; + default: goto yy39; + } +yy31: + YYDEBUG(31, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(32, *YYCURSOR); + if (yybm[0+yych] & 8) { + goto yy31; + } + YYDEBUG(33, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + /* ignore whitespace */ + + goto restart; +} +#line 434 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy34: + YYDEBUG(34, *YYCURSOR); + ++YYCURSOR; + if (yybm[0+(yych = *YYCURSOR)] & 8) { + goto yy31; + } +yy35: + YYDEBUG(35, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + return 0; +} +#line 448 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy36: + YYDEBUG(36, *YYCURSOR); + yych = *++YYCURSOR; + goto yy35; +yy37: + YYDEBUG(37, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'F') goto yy106; + if (yych == 'f') goto yy106; + goto yy40; +yy38: + YYDEBUG(38, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 125 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = zend_strndup(yytext, yyleng); + yylval->len = yyleng; + return T_ID; +} +#line 470 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy39: + YYDEBUG(39, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(3); + yych = *YYCURSOR; +yy40: + YYDEBUG(40, *YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy39; + } + if (yych <= '9') goto yy38; + goto yy62; +yy41: + YYDEBUG(41, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy42; + } + goto yy40; +yy42: + YYDEBUG(42, *YYCURSOR); + yyaccept = 1; + YYMARKER = ++YYCURSOR; + YYFILL(3); + yych = *YYCURSOR; + YYDEBUG(43, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy42; + } + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy44; + if (yych <= 0x08) goto yy39; + } else { + if (yych != '\r') goto yy39; + } + } else { + if (yych <= '#') { + if (yych <= ' ') goto yy44; + if (yych <= '"') goto yy39; + } else { + if (yych == ':') goto yy62; + goto yy39; + } + } +yy44: + YYDEBUG(44, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 106 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = atoi(yytext); + return T_DIGITS; +} +#line 527 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy45: + YYDEBUG(45, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy42; + } + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy44; + if (yych <= 0x08) goto yy40; + goto yy44; + } else { + if (yych == '\r') goto yy44; + goto yy40; + } + } else { + if (yych <= '#') { + if (yych <= ' ') goto yy44; + if (yych <= '"') goto yy40; + goto yy44; + } else { + if (yych == 'x') goto yy102; + goto yy40; + } + } +yy46: + YYDEBUG(46, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'I') goto yy96; + if (yych == 'i') goto yy96; + goto yy40; +yy47: + YYDEBUG(47, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'N') goto yy91; + if (yych == 'n') goto yy91; + goto yy40; +yy48: + YYDEBUG(48, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'A') goto yy88; + if (yych == 'a') goto yy88; + goto yy40; +yy49: + YYDEBUG(49, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'O') goto yy84; + if (yych == 'o') goto yy84; + goto yy40; +yy50: + YYDEBUG(50, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 'N') { + if (yych == 'F') goto yy83; + if (yych <= 'M') goto yy40; + goto yy77; + } else { + if (yych <= 'f') { + if (yych <= 'e') goto yy40; + goto yy83; + } else { + if (yych == 'n') goto yy77; + goto yy40; + } + } +yy51: + YYDEBUG(51, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'R') goto yy81; + if (yych == 'r') goto yy81; + goto yy40; +yy52: + YYDEBUG(52, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy76; + if (yych == 'e') goto yy76; + goto yy40; +yy53: + YYDEBUG(53, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy73; + goto yy40; +yy54: + YYDEBUG(54, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'e') goto yy61; + goto yy40; +yy55: + YYDEBUG(55, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(56, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 84 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + return T_POUND; +} +#line 634 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy57: + YYDEBUG(57, *YYCURSOR); + ++YYCURSOR; + if ((yych = *YYCURSOR) == ':') goto yy59; + YYDEBUG(58, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 90 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + return T_COLON; +} +#line 645 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy59: + YYDEBUG(59, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(60, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 87 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + return T_DCOLON; +} +#line 655 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy61: + YYDEBUG(61, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'n') goto yy67; + goto yy40; +yy62: + YYDEBUG(62, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '/') goto yy64; +yy63: + YYDEBUG(63, *YYCURSOR); + YYCURSOR = YYMARKER; + if (yyaccept <= 1) { + if (yyaccept <= 0) { + goto yy38; + } else { + goto yy44; + } + } else { + if (yyaccept <= 2) { + goto yy72; + } else { + goto yy105; + } + } +yy64: + YYDEBUG(64, *YYCURSOR); + yych = *++YYCURSOR; + if (yych != '/') goto yy63; + YYDEBUG(65, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(66, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 78 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = zend_strndup(yytext, yyleng); + yylval->len = yyleng; + return T_PROTO; +} +#line 697 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy67: + YYDEBUG(67, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych != 'd') goto yy40; + YYDEBUG(68, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych != '_') goto yy40; +yy69: + YYDEBUG(69, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy70; + } + goto yy40; +yy70: + YYDEBUG(70, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(3); + yych = *YYCURSOR; + YYDEBUG(71, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy70; + } + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy72; + if (yych <= 0x08) goto yy39; + } else { + if (yych != '\r') goto yy39; + } + } else { + if (yych <= '#') { + if (yych <= ' ') goto yy72; + if (yych <= '"') goto yy39; + } else { + if (yych == ':') goto yy62; + goto yy39; + } + } +yy72: + YYDEBUG(72, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 118 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + phpdbg_init_param(yylval, OP_PARAM); + yylval->str = zend_strndup(yytext, yyleng); + yylval->len = yyleng; + return T_OPCODE; +} +#line 751 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy73: + YYDEBUG(73, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych != 'N') goto yy40; + YYDEBUG(74, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych != 'D') goto yy40; + YYDEBUG(75, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == '_') goto yy69; + goto yy40; +yy76: + YYDEBUG(76, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'S') goto yy77; + if (yych != 's') goto yy40; +yy77: + YYDEBUG(77, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy40; + if (yych >= '\v') goto yy40; + } else { + if (yych <= '\r') goto yy78; + if (yych != ' ') goto yy40; + } +yy78: + YYDEBUG(78, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(79, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy80; + if (yych <= '\n') goto yy78; + } else { + if (yych <= '\r') goto yy78; + if (yych == ' ') goto yy78; + } +yy80: + YYDEBUG(80, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 94 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = 1; + return T_TRUTHY; +} +#line 805 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy81: + YYDEBUG(81, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'U') goto yy82; + if (yych != 'u') goto yy40; +yy82: + YYDEBUG(82, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy77; + if (yych == 'e') goto yy77; + goto yy40; +yy83: + YYDEBUG(83, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'F') goto yy84; + if (yych != 'f') goto yy40; +yy84: + YYDEBUG(84, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy40; + if (yych >= '\v') goto yy40; + } else { + if (yych <= '\r') goto yy85; + if (yych != ' ') goto yy40; + } +yy85: + YYDEBUG(85, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(86, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy87; + if (yych <= '\n') goto yy85; + } else { + if (yych <= '\r') goto yy85; + if (yych == ' ') goto yy85; + } +yy87: + YYDEBUG(87, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 100 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = 0; + return T_FALSY; +} +#line 858 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy88: + YYDEBUG(88, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'L') goto yy89; + if (yych != 'l') goto yy40; +yy89: + YYDEBUG(89, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'S') goto yy90; + if (yych != 's') goto yy40; +yy90: + YYDEBUG(90, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy84; + if (yych == 'e') goto yy84; + goto yy40; +yy91: + YYDEBUG(91, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'A') goto yy92; + if (yych != 'a') goto yy40; +yy92: + YYDEBUG(92, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'B') goto yy93; + if (yych != 'b') goto yy40; +yy93: + YYDEBUG(93, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'L') goto yy94; + if (yych != 'l') goto yy40; +yy94: + YYDEBUG(94, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy95; + if (yych != 'e') goto yy40; +yy95: + YYDEBUG(95, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'D') goto yy77; + if (yych == 'd') goto yy77; + goto yy40; +yy96: + YYDEBUG(96, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'S') goto yy97; + if (yych != 's') goto yy40; +yy97: + YYDEBUG(97, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'A') goto yy98; + if (yych != 'a') goto yy40; +yy98: + YYDEBUG(98, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'B') goto yy99; + if (yych != 'b') goto yy40; +yy99: + YYDEBUG(99, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'L') goto yy100; + if (yych != 'l') goto yy40; +yy100: + YYDEBUG(100, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy101; + if (yych != 'e') goto yy40; +yy101: + YYDEBUG(101, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'D') goto yy84; + if (yych == 'd') goto yy84; + goto yy40; +yy102: + YYDEBUG(102, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy103; + } + goto yy40; +yy103: + YYDEBUG(103, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(3); + yych = *YYCURSOR; + YYDEBUG(104, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy103; + } + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy105; + if (yych <= 0x08) goto yy39; + } else { + if (yych != '\r') goto yy39; + } + } else { + if (yych <= '#') { + if (yych <= ' ') goto yy105; + if (yych <= '"') goto yy39; + } else { + if (yych == ':') goto yy62; + goto yy39; + } + } +yy105: + YYDEBUG(105, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 112 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + phpdbg_init_param(yylval, ADDR_PARAM); + yylval->addr = strtoul(yytext, 0, 16); + return T_ADDR; +} +#line 989 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy106: + YYDEBUG(106, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy40; + if (yych >= '\v') goto yy40; + } else { + if (yych <= '\r') goto yy107; + if (yych != ' ') goto yy40; + } +yy107: + YYDEBUG(107, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(108, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy109; + if (yych <= '\n') goto yy107; + } else { + if (yych <= '\r') goto yy107; + if (yych == ' ') goto yy107; + } +yy109: + YYDEBUG(109, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 72 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + YYSETCONDITION(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_IF; +} +#line 1023 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" + } +/* *********************************** */ +yyc_RAW: + { + static const unsigned char yybm[] = { + 0, 64, 64, 64, 64, 64, 64, 64, + 64, 224, 128, 64, 64, 224, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 224, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 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(110, *YYCURSOR); + YYFILL(2); + yych = *YYCURSOR; + if (yybm[0+yych] & 32) { + goto yy112; + } + if (yych <= 0x00) goto yy117; + if (yych == '\n') goto yy115; + goto yy118; +yy112: + YYDEBUG(112, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(113, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy112; + } + if (yych <= 0x00) goto yy114; + if (yych == '\n') goto yy120; + goto yy118; +yy114: + YYDEBUG(114, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 132 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = zend_strndup(yytext, yyleng); + yylval->len = yyleng; + return T_INPUT; +} +#line 1093 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy115: + YYDEBUG(115, *YYCURSOR); + ++YYCURSOR; + if (yybm[0+(yych = *YYCURSOR)] & 128) { + goto yy120; + } +yy116: + YYDEBUG(116, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + return 0; +} +#line 1107 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy117: + YYDEBUG(117, *YYCURSOR); + yych = *++YYCURSOR; + goto yy116; +yy118: + YYDEBUG(118, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(119, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy118; + } + goto yy114; +yy120: + YYDEBUG(120, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(121, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy120; + } + YYDEBUG(122, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + /* ignore whitespace */ + + goto restart; +} +#line 1139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" + } +} +#line 168 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + +} diff --git a/sapi/phpdbg/phpdbg_lexer.h b/sapi/phpdbg/phpdbg_lexer.h new file mode 100644 index 0000000000..ab51e7daa8 --- /dev/null +++ b/sapi/phpdbg/phpdbg_lexer.h @@ -0,0 +1,41 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 <felipe@php.net> | + | Authors: Joe Watkins <joe.watkins@live.co.uk> | + | Authors: Bob Weinand <bwoebi@php.net> | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_LEXER_H +#define PHPDBG_LEXER_H + +#include "phpdbg_cmd.h" + +typedef struct { + unsigned int len; + unsigned char *text; + unsigned char *cursor; + unsigned char *marker; + int state; +} phpdbg_lexer_data; + +#define yyparse phpdbg_parse +#define yylex phpdbg_lex + +void phpdbg_init_lexer (phpdbg_param_t *stack, char *input TSRMLS_DC); + +int phpdbg_lex (phpdbg_param_t* yylval); + +#endif diff --git a/sapi/phpdbg/phpdbg_lexer.l b/sapi/phpdbg/phpdbg_lexer.l new file mode 100644 index 0000000000..7b3ce38c47 --- /dev/null +++ b/sapi/phpdbg/phpdbg_lexer.l @@ -0,0 +1,169 @@ +/* + * phpdbg_lexer.l + */ + +#include "phpdbg.h" +#include "phpdbg_cmd.h" + +#include "phpdbg_parser.h" + +#define LEX(v) (PHPDBG_G(lexer).v) + +#define YYCTYPE unsigned char +#define YYSETCONDITION(x) LEX(state) = x; +#define YYGETCONDITION() LEX(state) +#define YYCURSOR LEX(cursor) +#define YYMARKER LEX(marker) +#define yyleng LEX(len) +#define yytext ((char*) LEX(text)) +#undef YYDEBUG +#define YYDEBUG(a, b) +#define YYFILL(n) + +#define NORMAL 0 +#define RAW 1 +#define INITIAL 2 + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +void phpdbg_init_lexer (phpdbg_param_t *stack, char *input TSRMLS_DC) { + PHPDBG_G(parser_stack) = stack; + + YYSETCONDITION(INITIAL); + + LEX(text) = YYCURSOR = (unsigned char *) input; + LEX(len) = strlen(input); +} + +int phpdbg_lex (phpdbg_param_t* yylval) { + TSRMLS_FETCH(); /* Slow, but this is not a major problem here. TODO: Use TSRMLS_DC */ + +restart: + LEX(text) = YYCURSOR; + +/*!re2c +re2c:yyfill:check = 0; +T_TRUE 'true' +T_YES 'yes' +T_ON 'on' +T_ENABLED 'enabled' +T_FALSE 'false' +T_NO 'no' +T_OFF 'off' +T_DISABLED 'disabled' +T_EVAL 'ev' +T_SHELL 'sh' +T_IF 'if' +T_RUN 'run' +T_RUN_SHORT "r" +WS [ \r\n\t]+ +DIGITS [-]?[0-9\.]+ +ID [^ \r\n\t:#\000]+ +ADDR [0][x][a-fA-F0-9]+ +OPCODE (ZEND_|zend_)([A-Za-z])+ +INPUT [^\n\000]+ + +<!*> := yyleng = (size_t) YYCURSOR - (size_t) yytext; + +<*>[\n\000] { + return 0; +} + +<NORMAL>{T_IF}{WS} { + YYSETCONDITION(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_IF; +} + +<NORMAL>{ID}[:]{1}[//]{2} { + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = zend_strndup(yytext, yyleng); + yylval->len = yyleng; + return T_PROTO; +} +<NORMAL>[#]{1} { + return T_POUND; +} +<NORMAL>[:]{2} { + return T_DCOLON; +} +<NORMAL>[:]{1} { + return T_COLON; +} + +<NORMAL>({T_YES}|{T_ON}|{T_ENABLED}|{T_TRUE}){WS} { + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = 1; + return T_TRUTHY; +} + +<NORMAL>({T_NO}|{T_OFF}|{T_DISABLED}|{T_FALSE}){WS} { + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = 0; + return T_FALSY; +} + +<NORMAL>{DIGITS} { + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = atoi(yytext); + return T_DIGITS; +} + +<NORMAL>{ADDR} { + phpdbg_init_param(yylval, ADDR_PARAM); + yylval->addr = strtoul(yytext, 0, 16); + return T_ADDR; +} + +<NORMAL>{OPCODE} { + phpdbg_init_param(yylval, OP_PARAM); + yylval->str = zend_strndup(yytext, yyleng); + yylval->len = yyleng; + return T_OPCODE; +} + +<NORMAL>{ID} { + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = zend_strndup(yytext, yyleng); + yylval->len = yyleng; + return T_ID; +} + +<RAW>{INPUT} { + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = zend_strndup(yytext, yyleng); + yylval->len = yyleng; + return T_INPUT; +} + +<*>{WS} { + /* ignore whitespace */ + + goto restart; +} + +<INITIAL>{T_EVAL}{WS} { + YYSETCONDITION(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_EVAL; +} +<INITIAL>{T_SHELL}{WS} { + YYSETCONDITION(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_SHELL; +} +<INITIAL>({T_RUN}|{T_RUN_SHORT}){WS} { + YYSETCONDITION(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_RUN; +} + +<INITIAL>. { + YYSETCONDITION(NORMAL); + + YYCURSOR = LEX(text); + goto restart; +} + +*/ +} diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c index eb1091550b..e8db4e605c 100644 --- a/sapi/phpdbg/phpdbg_list.c +++ b/sapi/phpdbg/phpdbg_list.c @@ -29,9 +29,22 @@ #include "phpdbg.h" #include "phpdbg_list.h" #include "phpdbg_utils.h" +#include "phpdbg_prompt.h" +#include "php_streams.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +#define PHPDBG_LIST_COMMAND_D(f, h, a, m, l, s) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[13]) + +const phpdbg_command_t phpdbg_list_commands[] = { + PHPDBG_LIST_COMMAND_D(lines, "lists the specified lines", 'l', list_lines, NULL, "l"), + PHPDBG_LIST_COMMAND_D(class, "lists the specified class", 'c', list_class, NULL, "s"), + PHPDBG_LIST_COMMAND_D(method, "lists the specified method", 'm', list_method, NULL, "m"), + PHPDBG_LIST_COMMAND_D(func, "lists the specified function", 'f', list_func, NULL, "s"), + PHPDBG_END_COMMAND +}; + PHPDBG_LIST(lines) /* {{{ */ { if (!PHPDBG_G(exec) && !zend_is_executing(TSRMLS_C)) { @@ -41,12 +54,12 @@ PHPDBG_LIST(lines) /* {{{ */ 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), + (param->num < 0 ? 1 - param->num : param->num), + (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; @@ -59,41 +72,28 @@ PHPDBG_LIST(lines) /* {{{ */ PHPDBG_LIST(func) /* {{{ */ { - switch (param->type) { - case STR_PARAM: - phpdbg_list_function_byname( - param->str, param->len TSRMLS_CC); - break; - - phpdbg_default_switch_case(); - } + phpdbg_list_function_byname(param->str, param->len TSRMLS_CC); 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)); + zend_class_entry **ce; - 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); - } + 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)); - efree(lcname); - } else { - phpdbg_error("Could not find the class %s", param->method.class); - } - } break; + 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); + } - phpdbg_default_switch_case(); + efree(lcname); + } else { + phpdbg_error("Could not find the class %s", param->method.class); } return SUCCESS; @@ -101,30 +101,24 @@ PHPDBG_LIST(method) /* {{{ */ 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); - } + 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 requested class (%s) could not be found", param->str); + phpdbg_error("The source of the requested class (%s) cannot be found", (*ce)->name); } - } break; - - phpdbg_default_switch_case(); + } 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); } return SUCCESS; @@ -132,97 +126,57 @@ PHPDBG_LIST(class) /* {{{ */ 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; + char *opened = NULL; + char buffer[8096] = {0,}; + long line = 0; + php_stream *stream = NULL; + 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) { + stream = php_stream_open_wrapper(filename, "rb", USE_PATH, &opened); + + if (!stream) { 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; + + if (offset < 0) { + count += offset; + offset = 0; } - - 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; - } + + while (php_stream_gets(stream, buffer, sizeof(buffer)) != NULL) { + long linelen = strlen(buffer); ++line; - - if (!offset || offset <= line) { - /* Without offset, or offset reached */ + + if (offset <= line) { if (!highlight) { - phpdbg_writeln("%05u: %.*s", line, (int)(pos - last_pos), last_pos); + phpdbg_write("%05ld: %s", line, buffer); } else { if (highlight != line) { - phpdbg_writeln(" %05u: %.*s", line, (int)(pos - last_pos), last_pos); + phpdbg_write(" %05ld: %s", line, buffer); } else { - phpdbg_writeln(">%05u: %.*s", line, (int)(pos - last_pos), last_pos); + phpdbg_write(">%05ld: %s", line, buffer); } } - ++displayed; - } - last_pos = pos + 1; + if (buffer[linelen - 1] != '\n') { + phpdbg_write("\n"); + } + } - if (!all_content && displayed == count) { - /* Reached max line to display */ + if (count > 0 && count + offset - 1 < line) { break; } } - -#ifndef _WIN32 - munmap(mem, st.st_size); - close(fd); -#else - UnmapViewOfFile(mem); - CloseHandle(map); - CloseHandle(fd); -#endif + + php_stream_close(stream); } /* }}} */ void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */ diff --git a/sapi/phpdbg/phpdbg_list.h b/sapi/phpdbg/phpdbg_list.h index f9d1885eaf..14905f6567 100644 --- a/sapi/phpdbg/phpdbg_list.h +++ b/sapi/phpdbg/phpdbg_list.h @@ -36,12 +36,6 @@ 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 -}; +extern const phpdbg_command_t phpdbg_list_commands[]; #endif /* PHPDBG_LIST_H */ diff --git a/sapi/phpdbg/phpdbg_opcode.c b/sapi/phpdbg/phpdbg_opcode.c index 50073eb22b..6b13625fc1 100644 --- a/sapi/phpdbg/phpdbg_opcode.c +++ b/sapi/phpdbg/phpdbg_opcode.c @@ -183,6 +183,7 @@ void phpdbg_print_opline(zend_execute_data *execute_data, zend_bool ignore_flags const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */ { +#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO #define CASE(s) case s: return #s switch (opcode) { CASE(ZEND_NOP); @@ -360,4 +361,8 @@ const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */ default: return "UNKNOWN"; } +#else + const char *ret = zend_get_opcode_name(opcode); + return ret?ret:"UNKNOWN"; +#endif } /* }}} */ diff --git a/sapi/phpdbg/phpdbg_parser.c b/sapi/phpdbg/phpdbg_parser.c new file mode 100644 index 0000000000..e34c2f48ff --- /dev/null +++ b/sapi/phpdbg/phpdbg_parser.c @@ -0,0 +1,1911 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.6.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse phpdbg_parse +#define yylex phpdbg_lex +#define yyerror phpdbg_error +#define yylval phpdbg_lval +#define yychar phpdbg_char +#define yydebug phpdbg_debug +#define yynerrs phpdbg_nerrs + +/* Copy the first part of user declarations. */ +/* Line 336 of yacc.c */ +#line 1 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + + +/* + * phpdbg_parser.y + * (from php-src root) + * flex sapi/phpdbg/dev/phpdbg_lexer.l + * bison sapi/phpdbg/dev/phpdbg_parser.y + */ + +#include "phpdbg.h" +#include "phpdbg_cmd.h" +#include "phpdbg_utils.h" +#include "phpdbg_cmd.h" +#include "phpdbg_prompt.h" + +#define YYSTYPE phpdbg_param_t + +#include "phpdbg_parser.h" +#include "phpdbg_lexer.h" + +#undef yyerror +static int yyerror(void ***tsrm_ls, const char *msg); + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + + +/* Line 336 of yacc.c */ +#line 102 "sapi/phpdbg/phpdbg_parser.c" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "phpdbg_parser.h". */ +#ifndef PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H +# define PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int phpdbg_debug; +#endif +/* "%code requires" blocks. */ +/* Line 350 of yacc.c */ +#line 31 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +#include "phpdbg.h" +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + + +/* Line 350 of yacc.c */ +#line 143 "sapi/phpdbg/phpdbg_parser.c" + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_EVAL = 258, + T_RUN = 259, + T_SHELL = 260, + T_IF = 261, + T_TRUTHY = 262, + T_FALSY = 263, + T_STRING = 264, + T_COLON = 265, + T_DCOLON = 266, + T_POUND = 267, + T_PROTO = 268, + T_DIGITS = 269, + T_LITERAL = 270, + T_ADDR = 271, + T_OPCODE = 272, + T_ID = 273, + T_INPUT = 274, + T_UNEXPECTED = 275 + }; +#endif +/* Tokens. */ +#define T_EVAL 258 +#define T_RUN 259 +#define T_SHELL 260 +#define T_IF 261 +#define T_TRUTHY 262 +#define T_FALSY 263 +#define T_STRING 264 +#define T_COLON 265 +#define T_DCOLON 266 +#define T_POUND 267 +#define T_PROTO 268 +#define T_DIGITS 269 +#define T_LITERAL 270 +#define T_ADDR 271 +#define T_OPCODE 272 +#define T_ID 273 +#define T_INPUT 274 +#define T_UNEXPECTED 275 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int phpdbg_parse (void *YYPARSE_PARAM); +#else +int phpdbg_parse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int phpdbg_parse (void *tsrm_ls); +#else +int phpdbg_parse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H */ + +/* Copy the second part of user declarations. */ + +/* Line 353 of yacc.c */ +#line 220 "sapi/phpdbg/phpdbg_parser.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 25 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 42 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 21 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 5 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 25 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 38 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 275 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 5, 7, 8, 10, 13, 17, 22, + 27, 33, 37, 43, 47, 50, 52, 54, 56, 58, + 60, 62, 64, 67, 70, 72 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 22, 0, -1, 23, -1, 25, -1, -1, 24, -1, + 23, 24, -1, 18, 10, 14, -1, 18, 10, 12, + 14, -1, 13, 18, 10, 14, -1, 13, 18, 10, + 12, 14, -1, 18, 11, 18, -1, 18, 11, 18, + 12, 14, -1, 18, 12, 14, -1, 6, 19, -1, + 17, -1, 16, -1, 15, -1, 7, -1, 8, -1, + 14, -1, 18, -1, 3, 19, -1, 5, 19, -1, + 4, -1, 4, 19, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 66, 66, 67, 68, 72, 73, 77, 82, 87, + 97, 107, 112, 118, 124, 129, 130, 131, 132, 133, + 134, 135, 139, 144, 149, 153 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 1 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "\"eval\"", "\"run\"", "\"shell\"", + "\"if (condition)\"", "\"truthy (true, on, yes or enabled)\"", + "\"falsy (false, off, no or disabled)\"", + "\"string (some input, perhaps)\"", "\": (colon)\"", + "\":: (double colon)\"", "\"# (pound sign)\"", "\"protocol (file://)\"", + "\"digits (numbers)\"", "\"literal (string)\"", "\"address\"", + "\"opcode\"", "\"identifier (command or function name)\"", + "\"input (input string or data)\"", "\"input\"", "$accept", "input", + "parameters", "parameter", "full_expression", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 21, 22, 22, 22, 23, 23, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 25, 25, 25, 25 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 1, 0, 1, 2, 3, 4, 4, + 5, 3, 5, 3, 2, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 1, 2 +}; + +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 4, 0, 24, 0, 0, 18, 19, 0, 20, 17, + 16, 15, 21, 0, 2, 5, 3, 22, 25, 23, + 14, 0, 0, 0, 0, 1, 6, 0, 0, 7, + 11, 13, 0, 9, 8, 0, 10, 12 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 13, 14, 15, 16 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -11 +static const yytype_int8 yypact[] = +{ + -3, -10, 11, 12, 13, -11, -11, 15, -11, -11, + -11, -11, -4, 29, 10, -11, -11, -11, -11, -11, + -11, 24, 7, 17, 22, -11, -11, 8, 23, -11, + 26, -11, 25, -11, -11, 27, -11, -11 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -11, -11, -11, 28, -11 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 1, 2, 3, 4, 5, 6, 22, 23, 24, 17, + 7, 8, 9, 10, 11, 12, 4, 5, 6, 28, + 32, 29, 33, 7, 8, 9, 10, 11, 12, 25, + 18, 19, 20, 21, 27, 30, 31, 34, 35, 36, + 0, 37, 26 +}; + +#define yypact_value_is_default(yystate) \ + ((yystate) == (-11)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + +static const yytype_int8 yycheck[] = +{ + 3, 4, 5, 6, 7, 8, 10, 11, 12, 19, + 13, 14, 15, 16, 17, 18, 6, 7, 8, 12, + 12, 14, 14, 13, 14, 15, 16, 17, 18, 0, + 19, 19, 19, 18, 10, 18, 14, 14, 12, 14, + -1, 14, 14 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 4, 5, 6, 7, 8, 13, 14, 15, + 16, 17, 18, 22, 23, 24, 25, 19, 19, 19, + 19, 18, 10, 11, 12, 0, 24, 10, 12, 14, + 18, 14, 12, 14, 14, 12, 14, 14 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (tsrm_ls, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + + +/* This macro is provided for backward compatibility. */ + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, tsrm_ls); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, void *tsrm_ls) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, tsrm_ls) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + void *tsrm_ls; +#endif +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; + YYUSE (tsrm_ls); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, void *tsrm_ls) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, tsrm_ls) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + void *tsrm_ls; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep, tsrm_ls); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule, void *tsrm_ls) +#else +static void +yy_reduce_print (yyvsp, yyrule, tsrm_ls) + YYSTYPE *yyvsp; + int yyrule; + void *tsrm_ls; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , tsrm_ls); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule, tsrm_ls); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html> + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, void *tsrm_ls) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, tsrm_ls) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + void *tsrm_ls; +#endif +{ + YYUSE (yyvaluep); + YYUSE (tsrm_ls); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *tsrm_ls) +#else +int +yyparse (tsrm_ls) + void *tsrm_ls; +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 3: +/* Line 1802 of yacc.c */ +#line 67 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); } + break; + + case 5: +/* Line 1802 of yacc.c */ +#line 72 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); } + break; + + case 6: +/* Line 1802 of yacc.c */ +#line 73 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(2) - (2)])); } + break; + + case 7: +/* Line 1802 of yacc.c */ +#line 77 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = FILE_PARAM; + (yyval).file.name = (yyvsp[(2) - (3)]).str; + (yyval).file.line = (yyvsp[(3) - (3)]).num; + } + break; + + case 8: +/* Line 1802 of yacc.c */ +#line 82 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = NUMERIC_FILE_PARAM; + (yyval).file.name = (yyvsp[(1) - (4)]).str; + (yyval).file.line = (yyvsp[(4) - (4)]).num; + } + break; + + case 9: +/* Line 1802 of yacc.c */ +#line 87 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = FILE_PARAM; + (yyval).file.name = malloc((yyvsp[(1) - (4)]).len + (yyvsp[(2) - (4)]).len + 1); + if ((yyval).file.name) { + memcpy(&(yyval).file.name[0], (yyvsp[(1) - (4)]).str, (yyvsp[(1) - (4)]).len); + memcpy(&(yyval).file.name[(yyvsp[(1) - (4)]).len], (yyvsp[(2) - (4)]).str, (yyvsp[(2) - (4)]).len); + (yyval).file.name[(yyvsp[(1) - (4)]).len + (yyvsp[(2) - (4)]).len] = '\0'; + } + (yyval).file.line = (yyvsp[(4) - (4)]).num; + } + break; + + case 10: +/* Line 1802 of yacc.c */ +#line 97 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = NUMERIC_FILE_PARAM; + (yyval).file.name = malloc((yyvsp[(1) - (5)]).len + (yyvsp[(2) - (5)]).len + 1); + if ((yyval).file.name) { + memcpy(&(yyval).file.name[0], (yyvsp[(1) - (5)]).str, (yyvsp[(1) - (5)]).len); + memcpy(&(yyval).file.name[(yyvsp[(1) - (5)]).len], (yyvsp[(2) - (5)]).str, (yyvsp[(2) - (5)]).len); + (yyval).file.name[(yyvsp[(1) - (5)]).len + (yyvsp[(2) - (5)]).len] = '\0'; + } + (yyval).file.line = (yyvsp[(5) - (5)]).num; + } + break; + + case 11: +/* Line 1802 of yacc.c */ +#line 107 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = METHOD_PARAM; + (yyval).method.class = (yyvsp[(1) - (3)]).str; + (yyval).method.name = (yyvsp[(3) - (3)]).str; + } + break; + + case 12: +/* Line 1802 of yacc.c */ +#line 112 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = NUMERIC_METHOD_PARAM; + (yyval).method.class = (yyvsp[(1) - (5)]).str; + (yyval).method.name = (yyvsp[(3) - (5)]).str; + (yyval).num = (yyvsp[(5) - (5)]).num; + } + break; + + case 13: +/* Line 1802 of yacc.c */ +#line 118 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = NUMERIC_FUNCTION_PARAM; + (yyval).str = (yyvsp[(1) - (3)]).str; + (yyval).len = (yyvsp[(1) - (3)]).len; + (yyval).num = (yyvsp[(3) - (3)]).num; + } + break; + + case 14: +/* Line 1802 of yacc.c */ +#line 124 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = COND_PARAM; + (yyval).str = (yyvsp[(2) - (2)]).str; + (yyval).len = (yyvsp[(2) - (2)]).len; + } + break; + + case 15: +/* Line 1802 of yacc.c */ +#line 129 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 16: +/* Line 1802 of yacc.c */ +#line 130 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 17: +/* Line 1802 of yacc.c */ +#line 131 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 18: +/* Line 1802 of yacc.c */ +#line 132 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 19: +/* Line 1802 of yacc.c */ +#line 133 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 20: +/* Line 1802 of yacc.c */ +#line 134 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 21: +/* Line 1802 of yacc.c */ +#line 135 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 22: +/* Line 1802 of yacc.c */ +#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = EVAL_PARAM; + (yyval).str = (yyvsp[(2) - (2)]).str; + (yyval).len = (yyvsp[(2) - (2)]).len; + } + break; + + case 23: +/* Line 1802 of yacc.c */ +#line 144 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = SHELL_PARAM; + (yyval).str = (yyvsp[(2) - (2)]).str; + (yyval).len = (yyvsp[(2) - (2)]).len; + } + break; + + case 24: +/* Line 1802 of yacc.c */ +#line 149 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = RUN_PARAM; + (yyval).len = 0; + } + break; + + case 25: +/* Line 1802 of yacc.c */ +#line 153 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = RUN_PARAM; + (yyval).str = (yyvsp[(2) - (2)]).str; + (yyval).len = (yyvsp[(2) - (2)]).len; + } + break; + + +/* Line 1802 of yacc.c */ +#line 1657 "sapi/phpdbg/phpdbg_parser.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (tsrm_ls, YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (tsrm_ls, yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, tsrm_ls); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp, tsrm_ls); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (tsrm_ls, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, tsrm_ls); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, tsrm_ls); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +/* Line 2048 of yacc.c */ +#line 160 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + + +static int yyerror(void ***tsrm_ls, const char *msg) { + phpdbg_error("Parse Error: %s", msg); + + { + const phpdbg_param_t *top = PHPDBG_G(parser_stack); + + while (top) { + phpdbg_param_debug(top, "--> "); + top = top->next; + } + } + return 0; +} + +int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC) { + phpdbg_init_lexer(stack, input TSRMLS_CC); + +#ifdef ZTS + return yyparse(TSRMLS_C); +#else + return yyparse(NULL); +#endif +} diff --git a/sapi/phpdbg/phpdbg_parser.h b/sapi/phpdbg/phpdbg_parser.h new file mode 100644 index 0000000000..b3aadb9c62 --- /dev/null +++ b/sapi/phpdbg/phpdbg_parser.h @@ -0,0 +1,126 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H +# define PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int phpdbg_debug; +#endif +/* "%code requires" blocks. */ +/* Line 2055 of yacc.c */ +#line 31 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +#include "phpdbg.h" +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + + +/* Line 2055 of yacc.c */ +#line 55 "sapi/phpdbg/phpdbg_parser.h" + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_EVAL = 258, + T_RUN = 259, + T_SHELL = 260, + T_IF = 261, + T_TRUTHY = 262, + T_FALSY = 263, + T_STRING = 264, + T_COLON = 265, + T_DCOLON = 266, + T_POUND = 267, + T_PROTO = 268, + T_DIGITS = 269, + T_LITERAL = 270, + T_ADDR = 271, + T_OPCODE = 272, + T_ID = 273, + T_INPUT = 274, + T_UNEXPECTED = 275 + }; +#endif +/* Tokens. */ +#define T_EVAL 258 +#define T_RUN 259 +#define T_SHELL 260 +#define T_IF 261 +#define T_TRUTHY 262 +#define T_FALSY 263 +#define T_STRING 264 +#define T_COLON 265 +#define T_DCOLON 266 +#define T_POUND 267 +#define T_PROTO 268 +#define T_DIGITS 269 +#define T_LITERAL 270 +#define T_ADDR 271 +#define T_OPCODE 272 +#define T_ID 273 +#define T_INPUT 274 +#define T_UNEXPECTED 275 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int phpdbg_parse (void *YYPARSE_PARAM); +#else +int phpdbg_parse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int phpdbg_parse (void *tsrm_ls); +#else +int phpdbg_parse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H */ diff --git a/sapi/phpdbg/phpdbg_parser.y b/sapi/phpdbg/phpdbg_parser.y new file mode 100644 index 0000000000..702bf78455 --- /dev/null +++ b/sapi/phpdbg/phpdbg_parser.y @@ -0,0 +1,184 @@ +%{ + +/* + * phpdbg_parser.y + * (from php-src root) + * flex sapi/phpdbg/dev/phpdbg_lexer.l + * bison sapi/phpdbg/dev/phpdbg_parser.y + */ + +#include "phpdbg.h" +#include "phpdbg_cmd.h" +#include "phpdbg_utils.h" +#include "phpdbg_cmd.h" +#include "phpdbg_prompt.h" + +#define YYSTYPE phpdbg_param_t + +#include "phpdbg_parser.h" +#include "phpdbg_lexer.h" + +#undef yyerror +static int yyerror(void ***tsrm_ls, const char *msg); + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +%} + +%pure-parser +%error-verbose + +%code requires { +#include "phpdbg.h" +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif +} + +%parse-param { void *tsrm_ls } + +%output "sapi/phpdbg/phpdbg_parser.c" +%defines "sapi/phpdbg/phpdbg_parser.h" + +%token T_EVAL "eval" +%token T_RUN "run" +%token T_SHELL "shell" +%token T_IF "if (condition)" +%token T_TRUTHY "truthy (true, on, yes or enabled)" +%token T_FALSY "falsy (false, off, no or disabled)" +%token T_STRING "string (some input, perhaps)" +%token T_COLON ": (colon)" +%token T_DCOLON ":: (double colon)" +%token T_POUND "# (pound sign)" +%token T_PROTO "protocol (file://)" +%token T_DIGITS "digits (numbers)" +%token T_LITERAL "literal (string)" +%token T_ADDR "address" +%token T_OPCODE "opcode" +%token T_ID "identifier (command or function name)" +%token T_INPUT "input (input string or data)" +%token T_UNEXPECTED "input" + +%% /* Rules */ + +input + : parameters + | full_expression { phpdbg_stack_push(PHPDBG_G(parser_stack), &$1); } + | /* nothing */ + ; + +parameters + : parameter { phpdbg_stack_push(PHPDBG_G(parser_stack), &$1); } + | parameters parameter { phpdbg_stack_push(PHPDBG_G(parser_stack), &$2); } + ; + +parameter + : T_ID T_COLON T_DIGITS { + $$.type = FILE_PARAM; + $$.file.name = $2.str; + $$.file.line = $3.num; + } + | T_ID T_COLON T_POUND T_DIGITS { + $$.type = NUMERIC_FILE_PARAM; + $$.file.name = $1.str; + $$.file.line = $4.num; + } + | T_PROTO T_ID T_COLON T_DIGITS { + $$.type = FILE_PARAM; + $$.file.name = malloc($1.len + $2.len + 1); + if ($$.file.name) { + memcpy(&$$.file.name[0], $1.str, $1.len); + memcpy(&$$.file.name[$1.len], $2.str, $2.len); + $$.file.name[$1.len + $2.len] = '\0'; + } + $$.file.line = $4.num; + } + | T_PROTO T_ID T_COLON T_POUND T_DIGITS { + $$.type = NUMERIC_FILE_PARAM; + $$.file.name = malloc($1.len + $2.len + 1); + if ($$.file.name) { + memcpy(&$$.file.name[0], $1.str, $1.len); + memcpy(&$$.file.name[$1.len], $2.str, $2.len); + $$.file.name[$1.len + $2.len] = '\0'; + } + $$.file.line = $5.num; + } + | T_ID T_DCOLON T_ID { + $$.type = METHOD_PARAM; + $$.method.class = $1.str; + $$.method.name = $3.str; + } + | T_ID T_DCOLON T_ID T_POUND T_DIGITS { + $$.type = NUMERIC_METHOD_PARAM; + $$.method.class = $1.str; + $$.method.name = $3.str; + $$.num = $5.num; + } + | T_ID T_POUND T_DIGITS { + $$.type = NUMERIC_FUNCTION_PARAM; + $$.str = $1.str; + $$.len = $1.len; + $$.num = $3.num; + } + | T_IF T_INPUT { + $$.type = COND_PARAM; + $$.str = $2.str; + $$.len = $2.len; + } + | T_OPCODE { $$ = $1; } + | T_ADDR { $$ = $1; } + | T_LITERAL { $$ = $1; } + | T_TRUTHY { $$ = $1; } + | T_FALSY { $$ = $1; } + | T_DIGITS { $$ = $1; } + | T_ID { $$ = $1; } + ; + +full_expression + : T_EVAL T_INPUT { + $$.type = EVAL_PARAM; + $$.str = $2.str; + $$.len = $2.len; + } + | T_SHELL T_INPUT { + $$.type = SHELL_PARAM; + $$.str = $2.str; + $$.len = $2.len; + } + | T_RUN { + $$.type = RUN_PARAM; + $$.len = 0; + } + | T_RUN T_INPUT { + $$.type = RUN_PARAM; + $$.str = $2.str; + $$.len = $2.len; + } + ; + +%% + +static int yyerror(void ***tsrm_ls, const char *msg) { + phpdbg_error("Parse Error: %s", msg); + + { + const phpdbg_param_t *top = PHPDBG_G(parser_stack); + + while (top) { + phpdbg_param_debug(top, "--> "); + top = top->next; + } + } + return 0; +} + +int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC) { + phpdbg_init_lexer(stack, input TSRMLS_CC); + +#ifdef ZTS + return yyparse(TSRMLS_C); +#else + return yyparse(NULL); +#endif +} diff --git a/sapi/phpdbg/phpdbg_print.c b/sapi/phpdbg/phpdbg_print.c index c4925fe5fd..76321a5042 100644 --- a/sapi/phpdbg/phpdbg_print.c +++ b/sapi/phpdbg/phpdbg_print.c @@ -26,6 +26,19 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +#define PHPDBG_PRINT_COMMAND_D(f, h, a, m, l, s) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[9]) + +const phpdbg_command_t phpdbg_print_commands[] = { + PHPDBG_PRINT_COMMAND_D(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0), + PHPDBG_PRINT_COMMAND_D(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0), + PHPDBG_PRINT_COMMAND_D(class, "print out the instructions in the specified class", 'c', print_class, NULL, "s"), + PHPDBG_PRINT_COMMAND_D(method, "print out the instructions in the specified method", 'm', print_method, NULL, "m"), + PHPDBG_PRINT_COMMAND_D(func, "print out the instructions in the specified function", 'f', print_func, NULL, "s"), + PHPDBG_PRINT_COMMAND_D(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0), + PHPDBG_END_COMMAND +}; + PHPDBG_PRINT(opline) /* {{{ */ { if (EG(in_execution) && EG(current_execute_data)) { @@ -77,7 +90,7 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) phpdbg_error("\tFailed to decode opline %16p", opline); } opline++; - } while (++opcode < end); + } while (opcode++ < end); zend_hash_destroy(&vars); } } break; @@ -141,36 +154,30 @@ 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); + 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); } - } break; - - phpdbg_default_switch_case(); + } + } else { + phpdbg_error("The class %s could not be found", param->str); } return SUCCESS; @@ -178,31 +185,25 @@ PHPDBG_PRINT(class) /* {{{ */ 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)); + zend_class_entry **ce; - 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); + 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)); - phpdbg_print_function_helper(fbc TSRMLS_CC); - } else { - phpdbg_error("The method %s could not be found", 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); - efree(lcname); - } else { - phpdbg_error("The class %s could not be found", param->method.class); - } - } break; + phpdbg_print_function_helper(fbc TSRMLS_CC); + } else { + phpdbg_error("The method %s could not be found", param->method.name); + } - phpdbg_default_switch_case(); + efree(lcname); + } else { + phpdbg_error("The class %s could not be found", param->method.class); } return SUCCESS; @@ -210,49 +211,43 @@ PHPDBG_PRINT(method) /* {{{ */ 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); + 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); + } - phpdbg_print_function_helper(fbc TSRMLS_CC); - } else { - phpdbg_error("The function %s could not be found", func_name); - } + lcname = zend_str_tolower_dup(func_name, func_name_len); - efree(lcname); - } break; + 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_default_switch_case(); + phpdbg_print_function_helper(fbc TSRMLS_CC); + } else { + phpdbg_error("The function %s could not be found", func_name); } + efree(lcname); + return SUCCESS; } /* }}} */ diff --git a/sapi/phpdbg/phpdbg_print.h b/sapi/phpdbg/phpdbg_print.h index 80010d5e7c..ed85e965c1 100644 --- a/sapi/phpdbg/phpdbg_print.h +++ b/sapi/phpdbg/phpdbg_print.h @@ -35,17 +35,6 @@ 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 -}; +extern const phpdbg_command_t phpdbg_print_commands[]; #endif /* PHPDBG_PRINT_H */ diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index f586bb5a84..d91ef3f3f5 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -35,99 +35,152 @@ #include "phpdbg_cmd.h" #include "phpdbg_set.h" #include "phpdbg_frame.h" +#include "phpdbg_lexer.h" +#include "phpdbg_parser.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(exec, "set execution context", 'e', NULL, "s"), + PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 0), + PHPDBG_COMMAND_D(continue,"continue execution", 'c', NULL, 0), + PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s"), + PHPDBG_COMMAND_D(ev, "evaluate some code", 0, NULL, "i"), 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(print, "print something", 'p', phpdbg_print_commands, 0), + PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, "|*c"), + PHPDBG_COMMAND_D(back, "show trace", 't', NULL, "|n"), + PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, "|n"), + PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, "*"), + PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, "s"), 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(help, "show help menu", 'h', phpdbg_help_commands, "|s"), + PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, "s"), + PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s"), + PHPDBG_COMMAND_D(source, "execute a phpdbginit", '<', NULL, "s"), + PHPDBG_COMMAND_D(export, "export breaks to a .phpdbginit script", '>', NULL, "s"), + PHPDBG_COMMAND_D(sh, "shell a command", 0, NULL, "i"), PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), + PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss"), PHPDBG_END_COMMAND }; /* }}} */ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -static inline int phpdbg_call_register(phpdbg_input_t *input TSRMLS_DC) /* {{{ */ +static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ */ { - phpdbg_input_t *function = input->argv[0]; + phpdbg_param_t *name = NULL; - 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); + if (stack->type == STACK_PARAM) { + name = stack->next; + + if (!name || name->type != STR_PARAM) { + return FAILURE; + } + + if (zend_hash_exists( + &PHPDBG_G(registered), name->str, name->len+1)) { + + zval fname, *fretval; + zend_fcall_info fci; + + ZVAL_STRINGL(&fname, name->str, name->len, 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 (name->next) { + zval params; + phpdbg_param_t *next = name->next; + + array_init(¶ms); + + while (next) { + char *buffered = NULL; + + switch (next->type) { + case OP_PARAM: + case COND_PARAM: + case STR_PARAM: + add_next_index_stringl( + ¶ms, + next->str, + next->len, 1); + break; + + case NUMERIC_PARAM: + add_next_index_long(¶ms, next->num); + break; + + case METHOD_PARAM: + spprintf(&buffered, 0, "%s::%s", + next->method.class, next->method.name); + add_next_index_string(¶ms, buffered, 0); + break; + + case NUMERIC_METHOD_PARAM: + spprintf(&buffered, 0, "%s::%s#%ld", + next->method.class, next->method.name, next->num); + add_next_index_string(¶ms, buffered, 0); + break; + + case NUMERIC_FUNCTION_PARAM: + spprintf(&buffered, 0, "%s#%ld", + next->str, next->num); + add_next_index_string(¶ms, buffered, 0); + break; + + case FILE_PARAM: + spprintf(&buffered, 0, "%s:%ld", + next->file.name, next->file.line); + add_next_index_string(¶ms, buffered, 0); + break; + + case NUMERIC_FILE_PARAM: + spprintf(&buffered, 0, "%s:#%ld", + next->file.name, next->file.line); + add_next_index_string(¶ms, buffered, 0); + break; + + default: { + /* not yet */ + } + } + + next = next->next; + } - 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; } - zend_fcall_info_args(&fci, ¶ms TSRMLS_CC); - } else { - fci.params = NULL; - fci.param_count = 0; - } + phpdbg_debug( + "created %d params from arguments", + fci.param_count); - phpdbg_debug( - "created %d params from %d arguments", - fci.param_count, input->argc); + zend_call_function(&fci, NULL TSRMLS_CC); - zend_call_function(&fci, NULL TSRMLS_CC); - - if (fretval) { - zend_print_zval_r( - fretval, 0 TSRMLS_CC); - phpdbg_writeln(EMPTY); - } + if (fretval) { + zend_print_zval_r( + fretval, 0 TSRMLS_CC); + phpdbg_writeln(EMPTY); + } - zval_dtor(&fname); + zval_dtor(&fname); - return SUCCESS; + return SUCCESS; + } } return FAILURE; @@ -136,7 +189,7 @@ static inline int phpdbg_call_register(phpdbg_input_t *input TSRMLS_DC) /* {{{ * 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) { @@ -190,19 +243,34 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ } { - 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; + char *why = NULL; + char *input = phpdbg_read_input(cmd TSRMLS_CC); + phpdbg_param_t stack; + + phpdbg_init_param(&stack, STACK_PARAM); + + if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { + switch (phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { + case FAILURE: +// if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { + phpdbg_error( + "Unrecognized command in %s:%d: %s, %s!", + init_file, line, input, why); + } +// } + break; + } } + + if (why) { + free(why); + why = NULL; + } + + phpdbg_stack_free(&stack); phpdbg_destroy_input(&input TSRMLS_CC); } - } next_line: line++; @@ -264,47 +332,47 @@ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TS 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; - } + struct stat sb; - if (PHPDBG_G(ops)) { - phpdbg_notice("Destroying compiled opcodes"); - phpdbg_clean(0 TSRMLS_CC); - } + 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); - PHPDBG_G(exec) = res; - PHPDBG_G(exec_len) = res_len; + if ((res_len != PHPDBG_G(exec_len)) || (memcmp(res, PHPDBG_G(exec), res_len) != SUCCESS)) { - 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); + 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; + + *SG(request_info).argv = PHPDBG_G(exec); + php_hash_environment(TSRMLS_C); + + phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); + + if (phpdbg_compile(TSRMLS_C) == FAILURE) { + phpdbg_error("Failed to compile %s", PHPDBG_G(exec)); } } else { - phpdbg_error("Cannot stat %s, ensure the file exists", param->str); + phpdbg_notice("Execution context not changed"); } - } break; - - phpdbg_default_switch_case(); + } 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); } - return SUCCESS; } /* }}} */ @@ -312,6 +380,11 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */ { zend_file_handle fh; + if (!PHPDBG_G(exec)) { + phpdbg_error("No execution context"); + return SUCCESS; + } + if (EG(in_execution)) { phpdbg_error("Cannot compile while in execution"); return FAILURE; @@ -334,47 +407,16 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */ 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(); + if (EG(in_execution)) { + PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; } - return SUCCESS; + return PHPDBG_NEXT; } /* }}} */ -PHPDBG_COMMAND(next) /* {{{ */ +PHPDBG_COMMAND(continue) /* {{{ */ { return PHPDBG_NEXT; } /* }}} */ @@ -475,17 +517,9 @@ PHPDBG_COMMAND(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(); - } + if (!param) { + phpdbg_notice("Currently in frame #%d", PHPDBG_G(frame).num); + } else phpdbg_switch_frame(param->num TSRMLS_CC); return SUCCESS; } /* }}} */ @@ -580,6 +614,31 @@ PHPDBG_COMMAND(run) /* {{{ */ /* reset hit counters */ phpdbg_reset_breakpoints(TSRMLS_C); + if (param && param->type != EMPTY_PARAM && param->len != 0) { + char **argv = emalloc(5 * sizeof(char *)); + int argc = 0; + int i; + char *argv_str = strtok(param->str, " "); + + while (argv_str) { + if (argc >= 4 && argc == (argc & -argc)) { + argv = erealloc(argv, (argc * 2 + 1) * sizeof(char *)); + } + argv[++argc] = argv_str; + argv_str = strtok(0, " "); + argv[argc] = estrdup(argv[argc]); + } + argv[0] = SG(request_info).argv[0]; + for (i = SG(request_info).argc; --i;) { + efree(SG(request_info).argv[i]); + } + efree(SG(request_info).argv); + SG(request_info).argv = erealloc(argv, ++argc * sizeof(char *)); + SG(request_info).argc = argc; + + php_hash_environment(TSRMLS_C); + } + zend_try { php_output_activate(TSRMLS_C); PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; @@ -615,42 +674,36 @@ out: return SUCCESS; } /* }}} */ -PHPDBG_COMMAND(eval) /* {{{ */ +PHPDBG_COMMAND(ev) /* {{{ */ { - 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; + zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING)==PHPDBG_IS_STEPPING); + zval retval; - /* switch stepping back on */ - if (stepping && - !(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { - PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; - } + if (!(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { + PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING; + } - CG(unclean_shutdown) = 0; - } break; + /* 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; - phpdbg_default_switch_case(); + /* switch stepping back on */ + if (stepping && + !(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { + PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; } + CG(unclean_shutdown) = 0; + return SUCCESS; } /* }}} */ @@ -661,14 +714,10 @@ PHPDBG_COMMAND(back) /* {{{ */ 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(); + if (!param) { + phpdbg_dump_backtrace(0 TSRMLS_CC); + } else { + phpdbg_dump_backtrace(param->num TSRMLS_CC); } return SUCCESS; @@ -676,47 +725,46 @@ PHPDBG_COMMAND(back) /* {{{ */ PHPDBG_COMMAND(print) /* {{{ */ { - switch (param->type) { - case EMPTY_PARAM: { - phpdbg_writeln(SEPARATE); - phpdbg_notice("Execution Context Information"); + phpdbg_writeln(SEPARATE); + phpdbg_notice("Execution Context Information"); #ifdef HAVE_LIBREADLINE - phpdbg_writeln("Readline\tyes"); + phpdbg_writeln("Readline\tyes"); #else - phpdbg_writeln("Readline\tno"); + phpdbg_writeln("Readline\tno"); +#endif +#ifdef HAVE_LIBEDIT + phpdbg_writeln("Libedit\t\tyes"); +#else + phpdbg_writeln("Libedit\t\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); + 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)->last_var) { - phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1); - } else { - phpdbg_writeln("Variables\tNone"); - } - } + if (PHPDBG_G(ops)) { + phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last); - phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no"); - if (EG(in_execution)) { - phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret)); - } + if (PHPDBG_G(ops)->last_var) { + phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1); + } else { + phpdbg_writeln("Variables\tNone"); + } + } - 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("Executing\t%s", EG(in_execution) ? "yes" : "no"); + if (EG(in_execution)) { + phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret)); + } - phpdbg_writeln(SEPARATE); - } break; + 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_default_switch_case(); - } + phpdbg_writeln(SEPARATE); return SUCCESS; } /* }}} */ @@ -732,19 +780,18 @@ PHPDBG_COMMAND(info) /* {{{ */ PHPDBG_COMMAND(set) /* {{{ */ { phpdbg_error( - "No information command selected!"); + "No set command selected!"); return SUCCESS; } /* }}} */ PHPDBG_COMMAND(break) /* {{{ */ { - switch (param->type) { - case EMPTY_PARAM: - phpdbg_set_breakpoint_file( + if (!param) { + phpdbg_set_breakpoint_file( zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); - break; + } else switch (param->type) { case ADDR_PARAM: phpdbg_set_breakpoint_opline(param->addr TSRMLS_CC); break; @@ -767,9 +814,18 @@ PHPDBG_COMMAND(break) /* {{{ */ case FILE_PARAM: phpdbg_set_breakpoint_file(param->file.name, param->file.line TSRMLS_CC); break; + case NUMERIC_FILE_PARAM: + phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line TSRMLS_CC); + break; + case COND_PARAM: + phpdbg_set_breakpoint_expression(param->str, param->len TSRMLS_CC); + break; case STR_PARAM: phpdbg_set_breakpoint_symbol(param->str, param->len TSRMLS_CC); break; + case OP_PARAM: + phpdbg_set_breakpoint_opcode(param->str, param->len TSRMLS_CC); + break; phpdbg_default_switch_case(); } @@ -777,83 +833,72 @@ PHPDBG_COMMAND(break) /* {{{ */ return SUCCESS; } /* }}} */ -PHPDBG_COMMAND(shell) /* {{{ */ +PHPDBG_COMMAND(sh) /* {{{ */ { - /* 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(); + 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); } + 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; + struct stat sb; + + if (VCWD_STAT(param->str, &sb) != -1) { + phpdbg_try_file_init(param->str, param->len, 0 TSRMLS_CC); + } else { + phpdbg_error( + "Failed to stat %s, file does not exist", param->str); + } + + return SUCCESS; +} /* }}} */ - phpdbg_default_switch_case(); +PHPDBG_COMMAND(export) /* {{{ */ +{ + FILE *handle = VCWD_FOPEN(param->str, "w+"); + + if (handle) { + phpdbg_export_breakpoints(handle TSRMLS_CC); + fclose(handle); + } else { + phpdbg_error( + "Failed to open or create %s, check path and permissions", param->str); } + 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(); + 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); return SUCCESS; } /* }}} */ @@ -861,14 +906,11 @@ 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; + return PHPDBG_NEXT; } /* }}} */ PHPDBG_COMMAND(clean) /* {{{ */ @@ -908,100 +950,12 @@ PHPDBG_COMMAND(clear) /* {{{ */ 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) { + if (!param) { + return PHPDBG_LIST_HANDLER(lines)(PHPDBG_COMMAND_ARGS); + } else switch (param->type) { case NUMERIC_PARAM: - case EMPTY_PARAM: return PHPDBG_LIST_HANDLER(lines)(PHPDBG_COMMAND_ARGS); case FILE_PARAM: @@ -1020,54 +974,87 @@ PHPDBG_COMMAND(list) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_COMMAND(watch) /* {{{ */ +{ + if (!param || param->type == EMPTY_PARAM) { + phpdbg_list_watchpoints(TSRMLS_C); + } else switch (param->type) { + case STR_PARAM: + if (phpdbg_create_var_watchpoint(param->str, param->len TSRMLS_CC) != FAILURE) { + phpdbg_notice("Set watchpoint on %.*s", (int)param->len, param->str); + } + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + int phpdbg_interactive(TSRMLS_D) /* {{{ */ { int ret = SUCCESS; - phpdbg_input_t *input; + char *why = NULL; + char *input = NULL; + phpdbg_param_t stack; PHPDBG_G(flags) |= PHPDBG_IS_INTERACTIVE; input = phpdbg_read_input(NULL TSRMLS_CC); - if (input && input->length > 0L) { + if (input) { 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); + phpdbg_init_param(&stack, STACK_PARAM); + + if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { + switch (ret = phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { + case FAILURE: + if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { + if (why) { + phpdbg_error("%s", why); + } + } } - } - break; - case PHPDBG_LEAVE: - case PHPDBG_FINISH: - case PHPDBG_UNTIL: - case PHPDBG_NEXT: { - if (!EG(in_execution)) { - phpdbg_error("Not running"); + if (why) { + free(why); + why = NULL; + } + break; + + case PHPDBG_LEAVE: + case PHPDBG_FINISH: + case PHPDBG_UNTIL: + case PHPDBG_NEXT: { + if (!EG(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + phpdbg_error("Not running"); + } + goto out; } - goto out; } } - phpdbg_destroy_input(&input TSRMLS_CC); - } while ((input = phpdbg_read_input(NULL TSRMLS_CC)) && (input->length > 0L)); + if (why) { + free(why); + why = NULL; + } - if (input && !input->length) - goto last; + phpdbg_stack_free(&stack); + phpdbg_destroy_input(&input TSRMLS_CC); - } else { -last: - if (PHPDBG_G(lcmd)) { - ret = PHPDBG_G(lcmd)->handler( - &PHPDBG_G(lparam), input TSRMLS_CC); - goto out; - } + } while ((input = phpdbg_read_input(NULL TSRMLS_CC))); } out: - phpdbg_destroy_input(&input TSRMLS_CC); + if (input) { + phpdbg_stack_free(&stack); + phpdbg_destroy_input(&input TSRMLS_CC); + } + + if (why) { + free(why); + } if (EG(in_execution)) { phpdbg_restore_frame(TSRMLS_C); @@ -1075,6 +1062,8 @@ out: PHPDBG_G(flags) &= ~PHPDBG_IS_INTERACTIVE; + phpdbg_print_changed_zvals(TSRMLS_C); + return ret; } /* }}} */ @@ -1214,7 +1203,7 @@ zend_vm_enter: ); \ } \ \ - do { \ +/* do { */\ switch (phpdbg_interactive(TSRMLS_C)) { \ case PHPDBG_LEAVE: \ case PHPDBG_FINISH: \ @@ -1223,7 +1212,7 @@ zend_vm_enter: goto next; \ } \ } \ - } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); \ +/* } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); */\ } while (0) /* allow conditional breakpoints and @@ -1285,22 +1274,30 @@ zend_vm_enter: phpdbg_print_opline_ex( execute_data, &vars, 0 TSRMLS_CC); + if (PHPDBG_G(flags) & PHPDBG_IS_STEPPING && (PHPDBG_G(flags) & PHPDBG_STEP_OPCODE || execute_data->opline->lineno != PHPDBG_G(last_line))) { + PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; + DO_INTERACTIVE(); + } + + /* check if some watchpoint was hit */ + { + if (phpdbg_print_changed_zvals(TSRMLS_C) == SUCCESS) { + DO_INTERACTIVE(); + } + } + /* 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); + if ((PHPDBG_G(flags) & PHPDBG_BP_MASK) + && (brake = phpdbg_find_breakpoint(execute_data TSRMLS_CC)) + && (brake->type != PHPDBG_BREAK_FILE || execute_data->opline->lineno != PHPDBG_G(last_line))) { + 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); @@ -1309,6 +1306,8 @@ next: DO_INTERACTIVE(); } + PHPDBG_G(last_line) = execute_data->opline->lineno; + PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC); if (PHPDBG_G(vmret) > 0) { diff --git a/sapi/phpdbg/phpdbg_prompt.h b/sapi/phpdbg/phpdbg_prompt.h index 6807d88f41..ef648aabeb 100644 --- a/sapi/phpdbg/phpdbg_prompt.h +++ b/sapi/phpdbg/phpdbg_prompt.h @@ -30,11 +30,10 @@ 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(continue); PHPDBG_COMMAND(run); -PHPDBG_COMMAND(eval); +PHPDBG_COMMAND(ev); PHPDBG_COMMAND(until); PHPDBG_COMMAND(finish); PHPDBG_COMMAND(leave); @@ -47,13 +46,13 @@ PHPDBG_COMMAND(info); PHPDBG_COMMAND(clean); PHPDBG_COMMAND(clear); PHPDBG_COMMAND(help); -PHPDBG_COMMAND(quiet); -PHPDBG_COMMAND(aliases); -PHPDBG_COMMAND(shell); +PHPDBG_COMMAND(sh); PHPDBG_COMMAND(set); PHPDBG_COMMAND(source); +PHPDBG_COMMAND(export); PHPDBG_COMMAND(register); -PHPDBG_COMMAND(quit); /* }}} */ +PHPDBG_COMMAND(quit); +PHPDBG_COMMAND(watch); /* }}} */ /* {{{ prompt commands */ extern const phpdbg_command_t phpdbg_prompt_commands[]; /* }}} */ diff --git a/sapi/phpdbg/phpdbg_set.c b/sapi/phpdbg/phpdbg_set.c index 7c4da12a46..54269a8193 100644 --- a/sapi/phpdbg/phpdbg_set.c +++ b/sapi/phpdbg/phpdbg_set.c @@ -23,56 +23,52 @@ #include "phpdbg_set.h" #include "phpdbg_utils.h" #include "phpdbg_bp.h" +#include "phpdbg_prompt.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -PHPDBG_SET(prompt) /* {{{ */ -{ - switch (param->type) { - case EMPTY_PARAM: - phpdbg_writeln("%s", phpdbg_get_prompt(TSRMLS_C)); - break; +#define PHPDBG_SET_COMMAND_D(f, h, a, m, l, s) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[18]) - case STR_PARAM: - phpdbg_set_prompt(param->str TSRMLS_CC); - break; - - phpdbg_default_switch_case(); - } +const phpdbg_command_t phpdbg_set_commands[] = { + PHPDBG_SET_COMMAND_D(prompt, "usage: set prompt [<string>]", 'p', set_prompt, NULL, "|s"), +#ifndef _WIN32 + PHPDBG_SET_COMMAND_D(color, "usage: set color <element> <color>", 'c', set_color, NULL, "ss"), + PHPDBG_SET_COMMAND_D(colors, "usage: set colors [<on|off>]", 'C', set_colors, NULL, "|b"), +#endif + PHPDBG_SET_COMMAND_D(oplog, "usage: set oplog [<output>]", 'O', set_oplog, NULL, "|s"), + PHPDBG_SET_COMMAND_D(break, "usage: set break id [<on|off>]", 'b', set_break, NULL, "l|b"), + PHPDBG_SET_COMMAND_D(breaks, "usage: set breaks [<on|off>]", 'B', set_breaks, NULL, "|b"), + PHPDBG_SET_COMMAND_D(quiet, "usage: set quiet [<on|off>]", 'q', set_quiet, NULL, "|b"), + PHPDBG_SET_COMMAND_D(stepping, "usage: set stepping [<line|op>]", 's', set_stepping, NULL, "|s"), + PHPDBG_SET_COMMAND_D(refcount, "usage: set refcount [<on|off>]", 'r', set_refcount, NULL, "|b"), + PHPDBG_END_COMMAND +}; +PHPDBG_SET(prompt) /* {{{ */ +{ + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("%s", phpdbg_get_prompt(TSRMLS_C)); + } else phpdbg_set_prompt(param->str TSRMLS_CC); + 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); - } + if (param->next) { + if (param->next->num) { + phpdbg_enable_breakpoint(param->num TSRMLS_CC); + } else 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); + phpdbg_error("Failed to find breakpoint #%ld", param->num); } } } break; @@ -85,104 +81,96 @@ PHPDBG_SET(break) /* {{{ */ return SUCCESS; } /* }}} */ -#ifndef _WIN32 -PHPDBG_SET(color) /* {{{ */ +PHPDBG_SET(breaks) /* {{{ */ { - 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; + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("%s", + PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off"); + } else switch (param->type) { + case NUMERIC_PARAM: { + if (param->num) { + phpdbg_enable_breakpoints(TSRMLS_C); + } else phpdbg_disable_breakpoints(TSRMLS_C); + } break; - } else if (phpdbg_argv_is(1, "notice")) { - phpdbg_notice( - "setting notice color to %s (%s)", color->name, color->code); - element = PHPDBG_COLOR_NOTICE; + default: + phpdbg_error( + "set break used incorrectly: set break [id] <on|off>"); + } - } else goto usage; + return SUCCESS; +} /* }}} */ - /* 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: +#ifndef _WIN32 +PHPDBG_SET(color) /* {{{ */ +{ + const phpdbg_color_t *color = phpdbg_get_color( + param->next->str, param->next->len TSRMLS_CC); + + if (!color) { phpdbg_error( - "set color used incorrectly: set color <prompt|error|notice> <color>"); + "Failed to find the requested color (%s)", param->next->str); + return SUCCESS; } + + switch (phpdbg_get_element(param->str, param->len TSRMLS_CC)) { + case PHPDBG_COLOR_PROMPT: + phpdbg_notice( + "setting prompt color to %s (%s)", color->name, color->code); + if (PHPDBG_G(prompt)[1]) { + free(PHPDBG_G(prompt)[1]); + PHPDBG_G(prompt)[1]=NULL; + } + phpdbg_set_color(PHPDBG_COLOR_PROMPT, color TSRMLS_CC); + break; + + case PHPDBG_COLOR_ERROR: + phpdbg_notice( + "setting error color to %s (%s)", color->name, color->code); + phpdbg_set_color(PHPDBG_COLOR_ERROR, color TSRMLS_CC); + break; + + case PHPDBG_COLOR_NOTICE: + phpdbg_notice( + "setting notice color to %s (%s)", color->name, color->code); + phpdbg_set_color(PHPDBG_COLOR_NOTICE, color TSRMLS_CC); + break; + + default: + phpdbg_error( + "Failed to find the requested element (%s)", param->str); + } + 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) { + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("%s", PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "on" : "off"); + } else switch (param->type) { + case NUMERIC_PARAM: { + if (param->num) { PHPDBG_G(flags) |= PHPDBG_IS_COLOURED; - goto done; - } else if (strncasecmp(param->str, PHPDBG_STRL("off")) == 0) { + } else { PHPDBG_G(flags) &= ~PHPDBG_IS_COLOURED; - goto done; } - } + } break; default: phpdbg_error( "set colors used incorrectly: set colors <on|off>"); } -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; - + if (!param || param->type == EMPTY_PARAM) { + phpdbg_notice("Oplog %s", PHPDBG_G(oplog) ? "enabled" : "disabled"); + } else switch (param->type) { case STR_PARAM: { /* open oplog */ FILE *old = PHPDBG_G(oplog); @@ -206,3 +194,65 @@ PHPDBG_SET(oplog) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_SET(quiet) /* {{{ */ +{ + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("Quietness %s", + PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); + } else switch (param->type) { + case NUMERIC_PARAM: { + if (param->num) { + PHPDBG_G(flags) |= PHPDBG_IS_QUIET; + } else { + PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET; + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_SET(stepping) /* {{{ */ +{ + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("Stepping %s", + PHPDBG_G(flags) & PHPDBG_STEP_OPCODE ? "opcode" : "line"); + } else switch (param->type) { + case STR_PARAM: { + if ((param->len == sizeof("opcode")-1) && + (memcmp(param->str, "opcode", sizeof("opcode")) == SUCCESS)) { + PHPDBG_G(flags) |= PHPDBG_STEP_OPCODE; + } else if ((param->len == sizeof("line")-1) && + (memcmp(param->str, "line", sizeof("line")) == SUCCESS)) { + PHPDBG_G(flags) &= ~PHPDBG_STEP_OPCODE; + } else { + phpdbg_error("usage set stepping [<opcode|line>]"); + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_SET(refcount) /* {{{ */ +{ + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("Refcount %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); + } else switch (param->type) { + case NUMERIC_PARAM: { + if (param->num) { + PHPDBG_G(flags) |= PHPDBG_SHOW_REFCOUNTS; + } else { + PHPDBG_G(flags) &= ~PHPDBG_SHOW_REFCOUNTS; + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg_set.h b/sapi/phpdbg/phpdbg_set.h index 120aeb34f4..dea61ed382 100644 --- a/sapi/phpdbg/phpdbg_set.h +++ b/sapi/phpdbg/phpdbg_set.h @@ -32,16 +32,11 @@ PHPDBG_SET(colors); #endif PHPDBG_SET(oplog); PHPDBG_SET(break); +PHPDBG_SET(breaks); +PHPDBG_SET(quiet); +PHPDBG_SET(stepping); +PHPDBG_SET(refcount); -static const phpdbg_command_t phpdbg_set_commands[] = { - PHPDBG_COMMAND_D_EX(prompt, "usage: set prompt <string>", 'p', set_prompt, NULL, 0), -#ifndef _WIN32 - PHPDBG_COMMAND_D_EX(color, "usage: set color <element> <color>", 'c', set_color, NULL, 1), - PHPDBG_COMMAND_D_EX(colors, "usage: set colors <on|off>", 'C', set_colors, NULL, 1), -#endif - PHPDBG_COMMAND_D_EX(oplog, "usage: set oplog <output>", 'O', set_oplog, NULL, 0), - PHPDBG_COMMAND_D_EX(break, "usage: set break [id] <on|off>", 'b', set_break, NULL, 0), - PHPDBG_END_COMMAND -}; +extern const phpdbg_command_t phpdbg_set_commands[]; #endif /* PHPDBG_SET_H */ diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c index 1effcfccaf..3ce2fade17 100644 --- a/sapi/phpdbg/phpdbg_utils.c +++ b/sapi/phpdbg/phpdbg_utils.c @@ -30,6 +30,11 @@ #ifdef _WIN32 # include "win32/time.h" +#elif defined(HAVE_SYS_IOCTL_H) +# include "sys/ioctl.h" +# ifndef GWINSZ_IN_SYS_IOCTL +# include <termios.h> +# endif #endif ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -65,6 +70,14 @@ const static phpdbg_color_t colors[] = { PHPDBG_COLOR_END }; /* }}} */ +/* {{{ */ +const static phpdbg_element_t elements[] = { + PHPDBG_ELEMENT_D("prompt", PHPDBG_COLOR_PROMPT), + PHPDBG_ELEMENT_D("error", PHPDBG_COLOR_ERROR), + PHPDBG_ELEMENT_D("notice", PHPDBG_COLOR_NOTICE), + PHPDBG_ELEMENT_END +}; /* }}} */ + PHPDBG_API int phpdbg_is_numeric(const char *str) /* {{{ */ { if (!str) @@ -347,6 +360,21 @@ PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D) /* {{{ */ return colors; } /* }}} */ +PHPDBG_API int phpdbg_get_element(const char *name, size_t len TSRMLS_DC) { + const phpdbg_element_t *element = elements; + + while (element && element->name) { + if (len == element->name_length) { + if (strncasecmp(name, element->name, len) == SUCCESS) { + return element->id; + } + } + element++; + } + + return PHPDBG_COLOR_INVALID; +} + PHPDBG_API void phpdbg_set_prompt(const char *prompt TSRMLS_DC) /* {{{ */ { /* free formatted prompt */ @@ -372,12 +400,16 @@ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */ } /* create cached prompt */ +#ifndef HAVE_LIBEDIT + /* TODO: libedit doesn't seems to support coloured 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 { + } else +#endif + { asprintf( &PHPDBG_G(prompt)[1], "%s ", PHPDBG_G(prompt)[0]); @@ -385,3 +417,39 @@ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */ return PHPDBG_G(prompt)[1]; } /* }}} */ + +int phpdbg_rebuild_symtable(TSRMLS_D) { + if (!EG(active_op_array)) { + phpdbg_error("No active op array!"); + return FAILURE; + } + + if (!EG(active_symbol_table)) { + zend_rebuild_symbol_table(TSRMLS_C); + + if (!EG(active_symbol_table)) { + phpdbg_error("No active symbol table!"); + return FAILURE; + } + } + + return SUCCESS; +} + +PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D) /* {{{ */ +{ + int columns; +#ifdef _WIN32 + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; +#elif defined(HAVE_SYS_IOCTL_H) && defined (TIOCGWINSZ) + struct winsize w; + + columns = ioctl(fileno(stdout), TIOCGWINSZ, &w) == 0 ? w.ws_col : 80; +#else + columns = 80; +#endif + return columns; +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg_utils.h b/sapi/phpdbg/phpdbg_utils.h index c5164c3ac3..56bacfc459 100644 --- a/sapi/phpdbg/phpdbg_utils.h +++ b/sapi/phpdbg/phpdbg_utils.h @@ -85,12 +85,17 @@ PHPDBG_API int phpdbg_rlog(FILE *stream, const char *fmt, ...); {color, sizeof(color)-1, code} #define PHPDBG_COLOR_END \ {NULL, 0L, {0}} +#define PHPDBG_ELEMENT_LEN 3 +#define PHPDBG_ELEMENT_D(name, id) \ + {name, sizeof(name)-1, id} +#define PHPDBG_ELEMENT_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 +#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; @@ -98,13 +103,45 @@ typedef struct _phpdbg_color_t { const char code[PHPDBG_COLOR_LEN]; } phpdbg_color_t; +typedef struct _phpdbg_element_t { + char *name; + size_t name_length; + int id; +} phpdbg_element_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); /* }}} */ +PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D); +PHPDBG_API int phpdbg_get_element(const char *name, size_t len TSRMLS_DC); /* }}} */ /* {{{ Prompt Management */ PHPDBG_API void phpdbg_set_prompt(const char* TSRMLS_DC); PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D); /* }}} */ +/* {{{ Console Width */ +PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D); /* }}} */ + +int phpdbg_rebuild_symtable(TSRMLS_D); + +#if PHP_VERSION_ID < 50500 +/* copy from zend_hash.c PHP 5.5 for 5.4 compatibility */ +static void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos) { + Bucket *p; + + p = pos ? (*pos) : ht->pInternalPointer; + + if (!p) { + Z_TYPE_P(key) = IS_NULL; + } else if (p->nKeyLength) { + Z_TYPE_P(key) = IS_STRING; + 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; + Z_LVAL_P(key) = p->h; + } +} +#endif + #endif /* PHPDBG_UTILS_H */ diff --git a/sapi/phpdbg/phpdbg_watch.c b/sapi/phpdbg/phpdbg_watch.c new file mode 100644 index 0000000000..e88622444b --- /dev/null +++ b/sapi/phpdbg/phpdbg_watch.c @@ -0,0 +1,789 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 <felipe@php.net> | + | Authors: Joe Watkins <joe.watkins@live.co.uk> | + | Authors: Bob Weinand <bwoebi@php.net> | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "phpdbg.h" +#include "phpdbg_btree.h" +#include "phpdbg_watch.h" +#include "phpdbg_utils.h" +#ifndef _WIN32 +# include <unistd.h> +# include <sys/mman.h> +#endif + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + + +typedef struct { + void *page; + size_t size; + char reenable_writing; + /* data must be last element */ + void *data; +} phpdbg_watch_memdump; + +#define MEMDUMP_SIZE(size) (sizeof(phpdbg_watch_memdump) - sizeof(void *) + (size)) + + +static phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr TSRMLS_DC) { + phpdbg_watchpoint_t *watch; + phpdbg_btree_result *result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)phpdbg_get_page_boundary(addr) + phpdbg_pagesize - 1); + + if (result == NULL) { + return NULL; + } + + watch = result->ptr; + + /* check if that addr is in a mprotect()'ed memory area */ + if ((char *)phpdbg_get_page_boundary(watch->addr.ptr) > (char *)addr || (char *)phpdbg_get_page_boundary(watch->addr.ptr) + phpdbg_get_total_page_size(watch->addr.ptr, watch->size) < (char *)addr) { + /* failure */ + return NULL; + } + + return watch; +} + +static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int access TSRMLS_DC) { + int m; + + /* pagesize is assumed to be in the range of 2^x */ + m = mprotect(phpdbg_get_page_boundary(watch->addr.ptr), phpdbg_get_total_page_size(watch->addr.ptr, watch->size), access); +} + +static inline void phpdbg_activate_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_change_watchpoint_access(watch, PROT_READ TSRMLS_CC); +} + +static inline void phpdbg_deactivate_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_change_watchpoint_access(watch, PROT_READ | PROT_WRITE TSRMLS_CC); +} + +static inline void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr, watch); +} + +static inline void phpdbg_remove_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr); +} + +void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { + watch->addr.ptr = addr; + watch->size = size; +} + +void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { + phpdbg_create_addr_watchpoint(zv, sizeof(zval), watch); + watch->type = WATCH_ON_ZVAL; +} + +void phpdbg_create_ht_watchpoint(HashTable *ht, phpdbg_watchpoint_t *watch) { + phpdbg_create_addr_watchpoint(ht, sizeof(HashTable), watch); + watch->type = WATCH_ON_HASHTABLE; +} + +void phpdbg_watch_HashTable_dtor(zval **ptr); + +static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + watch->flags |= PHPDBG_WATCH_SIMPLE; + + phpdbg_store_watchpoint(watch TSRMLS_CC); + zend_hash_add(&PHPDBG_G(watchpoints), watch->str, watch->str_len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); + + if (watch->type == WATCH_ON_ZVAL) { + phpdbg_btree_insert(&PHPDBG_G(watch_HashTables), (zend_ulong)watch->parent_container, watch->parent_container->pDestructor); + watch->parent_container->pDestructor = (dtor_func_t)phpdbg_watch_HashTable_dtor; + } + + phpdbg_activate_watchpoint(watch TSRMLS_CC); + + return SUCCESS; +} + +static int phpdbg_create_array_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + HashTable *ht; + + switch (Z_TYPE_P(watch->addr.zv)) { + case IS_ARRAY: + ht = Z_ARRVAL_P(watch->addr.zv); + break; + case IS_OBJECT: + ht = Z_OBJPROP_P(watch->addr.zv); + break; + default: + return FAILURE; + } + + phpdbg_create_ht_watchpoint(ht, watch); + + phpdbg_create_watchpoint(watch TSRMLS_CC); + + return SUCCESS; +} + +static char *phpdbg_get_property_key(char *key) { + if (*key != 0) { + return key; + } + return strchr(key + 1, 0) + 1; +} + +static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + HashTable *ht; + + if (watch->type != WATCH_ON_ZVAL) { + return FAILURE; + } + + watch->flags |= PHPDBG_WATCH_RECURSIVE; + phpdbg_create_watchpoint(watch TSRMLS_CC); + + switch (Z_TYPE_P(watch->addr.zv)) { + case IS_ARRAY: + ht = Z_ARRVAL_P(watch->addr.zv); + break; + case IS_OBJECT: + ht = Z_OBJPROP_P(watch->addr.zv); + break; + default: + return SUCCESS; + } + + { + HashPosition position; + zval **zv; + zval key; + + for (zend_hash_internal_pointer_reset_ex(ht, &position); + zend_hash_get_current_data_ex(ht, (void **)&zv, &position) == SUCCESS; + zend_hash_move_forward_ex(ht, &position)) { + phpdbg_watchpoint_t *new_watch = emalloc(sizeof(phpdbg_watchpoint_t)); + + new_watch->flags = PHPDBG_WATCH_RECURSIVE; + new_watch->parent = watch; + new_watch->parent_container = ht; + + zend_hash_get_current_key_zval_ex(ht, &key, &position); + if (Z_TYPE(key) == IS_STRING) { + new_watch->name_in_parent = zend_strndup(Z_STRVAL(key), Z_STRLEN(key)); + new_watch->name_in_parent_len = Z_STRLEN(key); + } else { + new_watch->name_in_parent = NULL; + new_watch->name_in_parent_len = asprintf(&new_watch->name_in_parent, "%ld", Z_LVAL(key)); + } + + new_watch->str = NULL; + new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%s%s", (int)watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"[":"->", phpdbg_get_property_key(new_watch->name_in_parent), Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"]":""); + + phpdbg_create_zval_watchpoint(*zv, new_watch); + phpdbg_create_recursive_watchpoint(new_watch TSRMLS_CC); + } + } + + { + phpdbg_watchpoint_t *new_watch = emalloc(sizeof(phpdbg_watchpoint_t)); + + new_watch->parent = watch; + new_watch->parent_container = watch->parent_container; + new_watch->name_in_parent = zend_strndup(watch->name_in_parent, watch->name_in_parent_len); + new_watch->name_in_parent_len = watch->name_in_parent_len; + new_watch->str = NULL; + new_watch->str_len = asprintf(&new_watch->str, "%.*s[]", (int)watch->str_len, watch->str); + new_watch->flags = PHPDBG_WATCH_RECURSIVE; + + phpdbg_create_ht_watchpoint(ht, new_watch); + phpdbg_create_watchpoint(new_watch TSRMLS_CC); + } + + return SUCCESS; +} + +static int phpdbg_delete_watchpoint_recursive(phpdbg_watchpoint_t *watch, zend_bool user_request TSRMLS_DC) { + if (watch->type == WATCH_ON_HASHTABLE || (watch->type == WATCH_ON_ZVAL && (Z_TYPE_P(watch->addr.zv) == IS_ARRAY || Z_TYPE_P(watch->addr.zv) == IS_OBJECT))) { + HashTable *ht; + phpdbg_btree_result *result; + + if (watch->type == WATCH_ON_HASHTABLE && user_request) { + HashPosition position; + zval **zv; + zval key; + char *str; + int str_len; + phpdbg_watchpoint_t **watchpoint; + + ht = watch->addr.ht; + + for (zend_hash_internal_pointer_reset_ex(ht, &position); + zend_hash_get_current_data_ex(ht, (void **)&zv, &position) == SUCCESS; + zend_hash_move_forward_ex(ht, &position)) { + zend_hash_get_current_key_zval_ex(ht, &key, &position); + str = NULL; + if (Z_TYPE(key) == IS_STRING) { + str_len = asprintf(&str, "%.*s%s%s%s", (int)watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", phpdbg_get_property_key(Z_STRVAL(key)), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); + } else { + str_len = asprintf(&str, "%.*s%s%li%s", (int)watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", Z_LVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); + } + + if (zend_hash_find(&PHPDBG_G(watchpoints), str, str_len, (void **) &watchpoint) == SUCCESS) { + phpdbg_delete_watchpoint_recursive(*watchpoint, 1 TSRMLS_CC); + } + } + } else { + switch (Z_TYPE_P(watch->addr.zv)) { + case IS_ARRAY: + ht = Z_ARRVAL_P(watch->addr.zv); + break; + case IS_OBJECT: + ht = Z_OBJPROP_P(watch->addr.zv); + break; + } + + if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong) ht))) { + phpdbg_delete_watchpoint_recursive((phpdbg_watchpoint_t *) result->ptr, user_request TSRMLS_CC); + } + } + } + + return zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); +} + +static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) { + int ret; + phpdbg_watchpoint_t *watch; + phpdbg_btree_result *result; + + if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)tmp_watch->addr.ptr)) == NULL) { + return FAILURE; + } + + watch = result->ptr; + + if (watch->flags & PHPDBG_WATCH_RECURSIVE) { + ret = phpdbg_delete_watchpoint_recursive(watch, 1 TSRMLS_CC); + } else { + ret = zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + } + + free(tmp_watch->str); + efree(tmp_watch); + + return ret; +} + +static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, size_t i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC), zend_bool silent TSRMLS_DC) { + int ret = FAILURE; + zend_bool new_index = 1; + char *last_index; + int index_len = 0; + zval **zv; + + if (len < 2 || *input != '$') { + goto error; + } + + while (i++ < len) { + if (i == len) { + new_index = 1; + } else { + switch (input[i]) { + case '[': + new_index = 1; + break; + case ']': + break; + case '>': + if (last_index[index_len - 1] == '-') { + new_index = 1; + index_len--; + } + break; + + default: + if (new_index) { + last_index = input + i; + new_index = 0; + } + if (input[i - 1] == ']') { + goto error; + } + index_len++; + } + } + + if (new_index && index_len == 0) { + HashPosition position; + for (zend_hash_internal_pointer_reset_ex(parent, &position); + zend_hash_get_current_data_ex(parent, (void **)&zv, &position) == SUCCESS; + zend_hash_move_forward_ex(parent, &position)) { + if (i == len || (i == len - 1 && input[len - 1] == ']')) { + zval *key = emalloc(sizeof(zval)); + phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); + watch->flags = 0; + zend_hash_get_current_key_zval_ex(parent, key, &position); + convert_to_string(key); + watch->str = malloc(i + Z_STRLEN_P(key) + 2); + watch->str_len = sprintf(watch->str, "%.*s%s%s", (int)i, input, phpdbg_get_property_key(Z_STRVAL_P(key)), input[len - 1] == ']'?"]":""); + efree(key); + watch->name_in_parent = zend_strndup(last_index, index_len); + watch->name_in_parent_len = index_len; + watch->parent_container = parent; + phpdbg_create_zval_watchpoint(*zv, watch); + + ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; + } else if (Z_TYPE_PP(zv) == IS_OBJECT) { + phpdbg_watchpoint_parse_input(input, len, Z_OBJPROP_PP(zv), i, callback, silent TSRMLS_CC); + } else if (Z_TYPE_PP(zv) == IS_ARRAY) { + phpdbg_watchpoint_parse_input(input, len, Z_ARRVAL_PP(zv), i, callback, silent TSRMLS_CC); + } else { + /* Ignore silently */ + } + } + return ret; + } else if (new_index) { + char last_chr = last_index[index_len]; + last_index[index_len] = 0; + if (zend_symtable_find(parent, last_index, index_len + 1, (void **)&zv) == FAILURE) { + if (!silent) { + phpdbg_error("%.*s is undefined", (int)i, input); + } + return FAILURE; + } + last_index[index_len] = last_chr; + if (i == len) { + phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); + watch->flags = 0; + watch->str = zend_strndup(input, len); + watch->str_len = len; + watch->name_in_parent = zend_strndup(last_index, index_len); + watch->name_in_parent_len = index_len; + watch->parent_container = parent; + phpdbg_create_zval_watchpoint(*zv, watch); + + ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; + } else if (Z_TYPE_PP(zv) == IS_OBJECT) { + parent = Z_OBJPROP_PP(zv); + } else if (Z_TYPE_PP(zv) == IS_ARRAY) { + parent = Z_ARRVAL_PP(zv); + } else { + phpdbg_error("%.*s is nor an array nor an object", (int)i, input); + return FAILURE; + } + index_len = 0; + } + } + + return ret; + error: + phpdbg_error("Malformed input"); + return FAILURE; +} + +static int phpdbg_watchpoint_parse_symtables(char *input, size_t len, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) { + if (EG(This) && len >= 5 && !memcmp("$this", input, 5)) { + zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL); + } + + if (zend_is_auto_global(input, len TSRMLS_CC) && phpdbg_watchpoint_parse_input(input, len, &EG(symbol_table), 0, callback, 1 TSRMLS_CC) != FAILURE) { + return SUCCESS; + } + + return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, callback, 0 TSRMLS_CC); +} + +PHPDBG_WATCH(delete) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: + if (phpdbg_delete_var_watchpoint(param->str, param->len TSRMLS_CC) == FAILURE) { + phpdbg_error("Nothing was deleted, no corresponding watchpoint found"); + } else { + phpdbg_notice("Removed watchpoint %.*s", (int)param->len, param->str); + } + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_WATCH(recursive) /* {{{ */ +{ + if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { + return SUCCESS; + } + + switch (param->type) { + case STR_PARAM: + if (phpdbg_watchpoint_parse_symtables(param->str, param->len, phpdbg_create_recursive_watchpoint TSRMLS_CC) != FAILURE) { + phpdbg_notice("Set recursive watchpoint on %.*s", (int)param->len, param->str); + } + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_WATCH(array) /* {{{ */ +{ + if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { + return SUCCESS; + } + + switch (param->type) { + case STR_PARAM: + if (phpdbg_watchpoint_parse_symtables(param->str, param->len, phpdbg_create_array_watchpoint TSRMLS_CC) != FAILURE) { + phpdbg_notice("Set array watchpoint on %.*s", (int)param->len, param->str); + } + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +void phpdbg_watch_HashTable_dtor(zval **zv) { + phpdbg_btree_result *result; + TSRMLS_FETCH(); + + zval_ptr_dtor_wrapper(zv); + + if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)*zv))) { + phpdbg_watchpoint_t *watch = result->ptr; + + PHPDBG_G(watchpoint_hit) = 1; + + phpdbg_notice("%.*s was removed, removing watchpoint%s", (int)watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_RECURSIVE)?" recursively":""); + + if (watch->flags & PHPDBG_WATCH_RECURSIVE) { + phpdbg_delete_watchpoint_recursive(watch, 0 TSRMLS_CC); + } else { + zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + } + } +} + + +int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC) { + if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { + return FAILURE; + } + + return phpdbg_watchpoint_parse_symtables(input, len, phpdbg_create_watchpoint TSRMLS_CC); +} + +int phpdbg_delete_var_watchpoint(char *input, size_t len TSRMLS_DC) { + if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { + return FAILURE; + } + + return phpdbg_watchpoint_parse_symtables(input, len, phpdbg_delete_watchpoint TSRMLS_CC); +} + +#ifdef _WIN32 +int phpdbg_watchpoint_segfault_handler(void *addr TSRMLS_DC) { +#else +int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) { +#endif + void *page; + phpdbg_watch_memdump *dump; + phpdbg_watchpoint_t *watch; + size_t size; + + watch = phpdbg_check_for_watchpoint( +#ifdef _WIN32 + addr +#else + info->si_addr +#endif + TSRMLS_CC); + + if (watch == NULL) { + return FAILURE; + } + + page = phpdbg_get_page_boundary(watch->addr.ptr); + size = phpdbg_get_total_page_size(watch->addr.ptr, watch->size); + + /* re-enable writing */ + mprotect(page, size, PROT_READ | PROT_WRITE); + + dump = malloc(MEMDUMP_SIZE(size)); + dump->page = page; + dump->size = size; + + memcpy(&dump->data, page, size); + + zend_llist_add_element(&PHPDBG_G(watchlist_mem), &dump); + + return SUCCESS; +} + +void phpdbg_watchpoints_clean(TSRMLS_D) { + zend_hash_clean(&PHPDBG_G(watchpoints)); +} + +static void phpdbg_watch_dtor(void *pDest) { + phpdbg_watchpoint_t *watch = *(phpdbg_watchpoint_t **)pDest; + TSRMLS_FETCH(); + + phpdbg_deactivate_watchpoint(watch TSRMLS_CC); + phpdbg_remove_watchpoint(watch TSRMLS_CC); + + free(watch->str); + free(watch->name_in_parent); + efree(watch); +} + +static void phpdbg_watch_mem_dtor(void *llist_data) { + phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **)llist_data; + + /* Disble writing again */ + if (dump->reenable_writing) { + mprotect(dump->page, dump->size, PROT_READ); + } + + free(*(void **)llist_data); +} + +void phpdbg_setup_watchpoints(TSRMLS_D) { +#if _SC_PAGE_SIZE + phpdbg_pagesize = sysconf(_SC_PAGE_SIZE); +#elif _SC_PAGESIZE + phpdbg_pagesize = sysconf(_SC_PAGESIZE); +#elif _SC_NUTC_OS_PAGESIZE + phpdbg_pagesize = sysconf(_SC_NUTC_OS_PAGESIZE); +#else + phpdbg_pagesize = 4096; /* common pagesize */ +#endif + + zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 1); + phpdbg_btree_init(&PHPDBG_G(watchpoint_tree), sizeof(void *) * 8); + phpdbg_btree_init(&PHPDBG_G(watch_HashTables), sizeof(void *) * 8); + zend_hash_init(&PHPDBG_G(watchpoints), 8, NULL, phpdbg_watch_dtor, 0 ZEND_FILE_LINE_CC); +} + +static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { + /* fetch all changes between dump->page and dump->page + dump->size */ + phpdbg_btree_position pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), (zend_ulong)dump->page, (zend_ulong)dump->page + dump->size); + phpdbg_btree_result *result, *htresult; + int elementDiff; + void *curTest; + + dump->reenable_writing = 0; + + while ((result = phpdbg_btree_next(&pos))) { + phpdbg_watchpoint_t *watch = result->ptr, *htwatch; + void *oldPtr = (char *)&dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page); + char reenable = 1; + + if ((size_t)watch->addr.ptr < (size_t)dump->page || (size_t)watch->addr.ptr + watch->size > (size_t)dump->page + dump->size) { + continue; + } + + /* Test if the zval was separated and if necessary move the watchpoint */ + if (zend_hash_find(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1, &curTest) == SUCCESS) { + if (watch->type == WATCH_ON_HASHTABLE) { + switch (Z_TYPE_PP((zval **)curTest)) { + case IS_ARRAY: + curTest = (void *)Z_ARRVAL_PP((zval **)curTest); + break; + case IS_OBJECT: + curTest = (void *)Z_OBJPROP_PP((zval **)curTest); + break; + } + } else { + curTest = *(void **)curTest; + } + + if (curTest != watch->addr.ptr) { + phpdbg_deactivate_watchpoint(watch TSRMLS_CC); + phpdbg_remove_watchpoint(watch TSRMLS_CC); + watch->addr.ptr = curTest; + phpdbg_store_watchpoint(watch TSRMLS_CC); + phpdbg_activate_watchpoint(watch TSRMLS_CC); + + reenable = 0; + } + } + + /* Show to the user what changed and delete watchpoint upon removal */ + if (memcmp(oldPtr, watch->addr.ptr, watch->size) != SUCCESS) { + if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS || (watch->type == WATCH_ON_ZVAL && memcmp(oldPtr, watch->addr.zv, sizeof(zvalue_value))) || (watch->type == WATCH_ON_HASHTABLE +#if ZEND_DEBUG + && !watch->addr.ht->inconsistent +#endif + && zend_hash_num_elements((HashTable *)oldPtr) != zend_hash_num_elements(watch->addr.ht))) { + PHPDBG_G(watchpoint_hit) = 1; + + phpdbg_notice("Breaking on watchpoint %s", watch->str); + } + + switch (watch->type) { + case WATCH_ON_ZVAL: { + int removed = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_symtable_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1); + int show_value = memcmp(oldPtr, watch->addr.zv, sizeof(zvalue_value)); + int show_ref = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc || ((zval *)oldPtr)->is_ref__gc != watch->addr.zv->is_ref__gc; + + if (removed || show_value) { + phpdbg_write("Old value: "); + if ((Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) && removed) { + phpdbg_writeln("Value inaccessible, HashTable already destroyed"); + } else { + zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC); + phpdbg_writeln(""); + } + } + if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && (removed || show_ref)) { + phpdbg_writeln("Old refcount: %d; Old is_ref: %d", ((zval *)oldPtr)->refcount__gc, ((zval *)oldPtr)->is_ref__gc); + } + + /* check if zval was removed */ + if (removed) { + phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str); + zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + + reenable = 0; + + if (Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) { + goto remove_ht_watch; + } + + break; + } + + if (show_value) { + phpdbg_write("New value: "); + zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); + phpdbg_writeln(""); + } + if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && show_ref) { + phpdbg_writeln("New refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); + } + + if ((Z_TYPE_P(watch->addr.zv) == IS_ARRAY && Z_ARRVAL_P(watch->addr.zv) != Z_ARRVAL_P((zval *)oldPtr)) || (Z_TYPE_P(watch->addr.zv) != IS_OBJECT && Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *)oldPtr))) { + /* add new watchpoints if necessary */ + if (watch->flags & PHPDBG_WATCH_RECURSIVE) { + phpdbg_create_recursive_watchpoint(watch TSRMLS_CC); + } + } + + if ((Z_TYPE_P((zval *)oldPtr) != IS_ARRAY || Z_ARRVAL_P(watch->addr.zv) == Z_ARRVAL_P((zval *)oldPtr)) && (Z_TYPE_P((zval *)oldPtr) != IS_OBJECT || Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *)oldPtr))) { + break; + } + +remove_ht_watch: + if ((htresult = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)Z_ARRVAL_P((zval *)oldPtr)))) { + htwatch = htresult->ptr; + zend_hash_del(&PHPDBG_G(watchpoints), htwatch->str, htwatch->str_len); + } + + break; + } + case WATCH_ON_HASHTABLE: + +#if ZEND_DEBUG + if (watch->addr.ht->inconsistent) { + phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str); + zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + + reenable = 0; + + break; + } +#endif + + elementDiff = zend_hash_num_elements((HashTable *)oldPtr) - zend_hash_num_elements(watch->addr.ht); + if (elementDiff) { + if (elementDiff > 0) { + phpdbg_writeln("%d elements were removed from the array", elementDiff); + } else { + phpdbg_writeln("%d elements were added to the array", -elementDiff); + + /* add new watchpoints if necessary */ + if (watch->flags & PHPDBG_WATCH_RECURSIVE) { + phpdbg_create_recursive_watchpoint(watch TSRMLS_CC); + } + } + } + if (((HashTable *)oldPtr)->pInternalPointer != watch->addr.ht->pInternalPointer) { + phpdbg_writeln("Internal pointer of array was changed"); + } + break; + } + } + + dump->reenable_writing = dump->reenable_writing | reenable; + } +} + +int phpdbg_print_changed_zvals(TSRMLS_D) { + zend_llist_position pos; + phpdbg_watch_memdump **dump; + int ret; + + if (zend_llist_count(&PHPDBG_G(watchlist_mem)) == 0) { + return FAILURE; + } + + dump = (phpdbg_watch_memdump **)zend_llist_get_last_ex(&PHPDBG_G(watchlist_mem), &pos); + + do { + phpdbg_print_changed_zval(*dump TSRMLS_CC); + } while ((dump = (phpdbg_watch_memdump **)zend_llist_get_prev_ex(&PHPDBG_G(watchlist_mem), &pos))); + + zend_llist_clean(&PHPDBG_G(watchlist_mem)); + + ret = PHPDBG_G(watchpoint_hit)?SUCCESS:FAILURE; + PHPDBG_G(watchpoint_hit) = 0; + + return ret; +} + +void phpdbg_list_watchpoints(TSRMLS_D) { + HashPosition position; + phpdbg_watchpoint_t **watch; + + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(watchpoints), &position); + zend_hash_get_current_data_ex(&PHPDBG_G(watchpoints), (void**) &watch, &position) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(watchpoints), &position)) { + phpdbg_writeln("%.*s", (int)(*watch)->str_len, (*watch)->str); + } +} + +void phpdbg_watch_efree(void *ptr) { + phpdbg_btree_result *result; + TSRMLS_FETCH(); + + result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)ptr); + + if (result) { + phpdbg_watchpoint_t *watch = result->ptr; + + if ((size_t)watch->addr.ptr + watch->size > (size_t)ptr) { + zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + } + } + + PHPDBG_G(original_free_function)(ptr); +} diff --git a/sapi/phpdbg/phpdbg_watch.h b/sapi/phpdbg/phpdbg_watch.h new file mode 100644 index 0000000000..d00bcff77e --- /dev/null +++ b/sapi/phpdbg/phpdbg_watch.h @@ -0,0 +1,112 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 <felipe@php.net> | + | Authors: Joe Watkins <joe.watkins@live.co.uk> | + | Authors: Bob Weinand <bwoebi@php.net> | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_WATCH_H +#define PHPDBG_WATCH_H + +#include "TSRM.h" +#include "phpdbg_cmd.h" + +#ifdef _WIN32 +# include "phpdbg_win.h" +#endif + +#define PHPDBG_WATCH(name) PHPDBG_COMMAND(watch_##name) + +/** + * Printer Forward Declarations + */ +PHPDBG_WATCH(array); +PHPDBG_WATCH(delete); +PHPDBG_WATCH(recursive); + +/** + * Commands + */ + +static const phpdbg_command_t phpdbg_watch_commands[] = { + PHPDBG_COMMAND_D_EX(array, "create watchpoint on an array", 'a', watch_array, NULL, "s"), + PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, "s"), + PHPDBG_COMMAND_D_EX(recursive, "create recursive watchpoints", 'r', watch_recursive, NULL, "s"), + PHPDBG_END_COMMAND +}; + +/* Watchpoint functions/typedefs */ + +typedef enum { + WATCH_ON_ZVAL, + WATCH_ON_HASHTABLE, +} phpdbg_watchtype; + + +#define PHPDBG_WATCH_SIMPLE 0x0 +#define PHPDBG_WATCH_RECURSIVE 0x1 + +typedef struct _phpdbg_watchpoint_t phpdbg_watchpoint_t; + +struct _phpdbg_watchpoint_t { + phpdbg_watchpoint_t *parent; + HashTable *parent_container; + char *name_in_parent; + size_t name_in_parent_len; + char *str; + size_t str_len; + union { + zval *zv; + HashTable *ht; + void *ptr; + } addr; + size_t size; + phpdbg_watchtype type; + char flags; +}; + +void phpdbg_setup_watchpoints(TSRMLS_D); + +#ifndef _WIN32 +int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC); +#else +int phpdbg_watchpoint_segfault_handler(void *addr TSRMLS_DC); +#endif + +void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch); +void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch); + +int phpdbg_delete_var_watchpoint(char *input, size_t len TSRMLS_DC); +int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC); + +int phpdbg_print_changed_zvals(TSRMLS_D); + +void phpdbg_list_watchpoints(TSRMLS_D); + +void phpdbg_watch_efree(void *ptr); + + +static long phpdbg_pagesize; + +static zend_always_inline void *phpdbg_get_page_boundary(void *addr) { + return (void *)((size_t)addr & ~(phpdbg_pagesize - 1)); +} + +static zend_always_inline size_t phpdbg_get_total_page_size(void *addr, size_t size) { + return (size_t)phpdbg_get_page_boundary((void *)((size_t)addr + size - 1)) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize; +} + +#endif diff --git a/sapi/phpdbg/phpdbg_win.c b/sapi/phpdbg/phpdbg_win.c new file mode 100644 index 0000000000..b0cbdf267a --- /dev/null +++ b/sapi/phpdbg/phpdbg_win.c @@ -0,0 +1,42 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 <felipe@php.net> | + | Authors: Joe Watkins <joe.watkins@live.co.uk> | + | Authors: Bob Weinand <bwoebi@php.net> | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "phpdbg.h" + +int mprotect(void *addr, size_t size, int protection) { + int var; + return (int)VirtualProtect(addr, size, protection == (PROT_READ | PROT_WRITE) ? PAGE_READWRITE : PAGE_READONLY, &var); +} + +int phpdbg_exception_handler_win32(EXCEPTION_POINTERS *xp) { + EXCEPTION_RECORD *xr = xp->ExceptionRecord; + CONTEXT *xc = xp->ContextRecord; + + if(xr->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { + TSRMLS_FETCH(); + + if (phpdbg_watchpoint_segfault_handler((void *)xr->ExceptionInformation[1] TSRMLS_CC) == SUCCESS) { + return EXCEPTION_CONTINUE_EXECUTION; + } + } + + return EXCEPTION_CONTINUE_SEARCH; +} diff --git a/sapi/phpdbg/phpdbg_win.h b/sapi/phpdbg/phpdbg_win.h new file mode 100644 index 0000000000..68c3052790 --- /dev/null +++ b/sapi/phpdbg/phpdbg_win.h @@ -0,0 +1,37 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 <felipe@php.net> | + | Authors: Joe Watkins <joe.watkins@live.co.uk> | + | Authors: Bob Weinand <bwoebi@php.net> | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_WIN_H +#define PHPDBG_WIN_H + +#include "winbase.h" +#include "windows.h" +#include "excpt.h" + +#define PROT_READ 1 +#define PROT_WRITE 2 + +int mprotect(void *addr, size_t size, int protection); + +void phpdbg_win_set_mm_heap(zend_mm_heap *heap); + +int phpdbg_exception_handler_win32(EXCEPTION_POINTERS *xp); + +#endif
\ No newline at end of file diff --git a/sapi/phpdbg/test.php b/sapi/phpdbg/test.php index 5fdbcbe1a4..d93c81a89a 100644 --- a/sapi/phpdbg/test.php +++ b/sapi/phpdbg/test.php @@ -6,11 +6,16 @@ if (isset($include)) { $stdout = fopen("php://stdout", "w+"); class phpdbg { - public function isGreat($greeting = null) { - printf( - "%s: %s\n", __METHOD__, $greeting); - return $this; - } + private $sprintf = "%s: %s\n"; + + public function isGreat($greeting = null) { + printf($this->sprintf, __METHOD__, $greeting); + return $this; + } +} + +function mine() { + var_dump(func_get_args()); } function test($x, $y = 0) { @@ -49,3 +54,34 @@ function phpdbg_test_ob() echo 'End'; echo $b; } + +$array = [ + 1, + 2, + [3, 4], + [5, 6], +]; + +$array[] = 7; + +array_walk($array, function (&$item) { + if (is_array($item)) + $item[0] += 2; + else + $item -= 1; +}); + +class testClass { + public $a = 2; + protected $b = [1, 3]; + private $c = 7; +} + +$obj = new testClass; + +$test = $obj->a; + +$obj->a += 2; +$test -= 2; + +unset($obj); diff --git a/sapi/phpdbg/tests/commands/0002_set.test b/sapi/phpdbg/tests/commands/0002_set.test index 7720f94fff..468ac6d9ea 100644 --- a/sapi/phpdbg/tests/commands/0002_set.test +++ b/sapi/phpdbg/tests/commands/0002_set.test @@ -9,7 +9,6 @@ # setting notice color # Failed to find breakpoint #0 # oplog disabled -# not enabled # opened oplog test.log # nothing ################################################# @@ -19,5 +18,4 @@ 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/0103_register.test b/sapi/phpdbg/tests/commands/0103_register.test index 38841591ca..703a12f771 100644 --- a/sapi/phpdbg/tests/commands/0103_register.test +++ b/sapi/phpdbg/tests/commands/0103_register.test @@ -7,15 +7,15 @@ #[Registered test_function] #array(5) { # [0]=> -# string(1) "1" +# int(1) # [1]=> -# string(1) "2" +# int(2) # [2]=> -# string(1) "3" +# int(3) # [3]=> -# string(1) "4" +# int(4) # [4]=> -# string(1) "5" +# int(5) #} ################################################# <: diff --git a/sapi/phpdbg/tests/commands/0106_compile.test b/sapi/phpdbg/tests/commands/0106_compile.test index d79211ddf7..7193600ea3 100644 --- a/sapi/phpdbg/tests/commands/0106_compile.test +++ b/sapi/phpdbg/tests/commands/0106_compile.test @@ -14,6 +14,5 @@ define('OUT', file_put_contents(OUT, "<?php echo \"Hello World\"; ?>"); phpdbg_exec(OUT); :> -compile run quit diff --git a/sapi/phpdbg/tests/run-tests.php b/sapi/phpdbg/tests/run-tests.php index 1fb6fa1224..1cc31d815e 100644 --- a/sapi/phpdbg/tests/run-tests.php +++ b/sapi/phpdbg/tests/run-tests.php @@ -135,8 +135,8 @@ namespace phpdbg\testing { * @param array basic configuration * @param array command line */ - public function __construct(TestsConfiguration &$config) { - $this->config = &$config; + public function __construct(TestsConfiguration $config) { + $this->config = $config; if ($this->config->hasFlag('help') || $this->config->hasFlag('h')) { @@ -153,7 +153,7 @@ namespace phpdbg\testing { $paths = array(); $where = ($in != null) ? array($in) : $this->config['path']; - foreach ($where as &$path) { + foreach ($where as $path) { if ($path) { if (is_dir($path)) { $paths[] = $path; @@ -243,6 +243,7 @@ namespace phpdbg\testing { 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-diff2stdout\t\twrite diff to stdout instead of files%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); @@ -266,9 +267,11 @@ namespace phpdbg\testing { $test = sprintf('%s/%s', $path, $file); if (preg_match('~\.test$~', $test)) { - yield new Test($this->config, $test); + $tests[] = new Test($this->config, $test); } } + + return $tests; } /** @@ -284,6 +287,8 @@ namespace phpdbg\testing { $test->purpose, $result ? "PASS" : "FAIL", PHP_EOL); + + return $result; } protected $config; @@ -352,7 +357,7 @@ namespace phpdbg\testing { * @param array configuration * @param string file */ - public function __construct(TestsConfiguration &$config, &$file) { + public function __construct(TestsConfiguration $config, $file) { if (($handle = fopen($file, 'r'))) { while (($line = fgets($handle))) { $trim = trim($line); @@ -415,8 +420,8 @@ namespace phpdbg\testing { } fclose($handle); - $this->config = &$config; - $this->file = &$file; + $this->config = $config; + $this->file = $file; } } @@ -425,8 +430,7 @@ namespace phpdbg\testing { * */ public function getResult() { - $options = sprintf( - '-i%s -qb', $this->file); + $options = sprintf('-i%s -nqb', $this->file); if ($this->options) { $options = sprintf( @@ -492,13 +496,18 @@ namespace phpdbg\testing { * */ 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+'))) { + if (!$this->config->hasFlag('nodiff')) { + if ($this->config->hasFlag('diff2stdout')) { + $difffile = "php://stdout"; + file_put_contents($difffile, "====DIFF====\n"); + } else { + $difffile = sprintf( + '%s/%s.diff', + dirname($this->file), basename($this->file)); + } + + if (($diff = fopen($difffile, 'w+'))) { foreach ($this->diff['wants'] as $line => $want) { $got = $this->diff['gets'][$line]; @@ -519,7 +528,7 @@ namespace phpdbg\testing { * Write log to disk if configuration allows it * */ - protected function writeLog(&$result = null) { + protected function writeLog($result = null) { $log = sprintf( '%s/%s.log', dirname($this->file), basename($this->file)); @@ -552,6 +561,9 @@ namespace { $cwd = dirname(__FILE__); $cmd = $_SERVER['argv']; + + $retval = 0; + { $config = new TestsConfiguration(array( 'exec' => realpath(array_shift($cmd)), @@ -571,7 +583,7 @@ namespace { $tests->logPath($path); foreach ($tests->findTests($path) as $test) { - $tests->logTest($path, $test); + $retval |= !$tests->logTest($path, $test); } $tests->logPathStats($path); @@ -579,5 +591,7 @@ namespace { $tests->logStats(); } + + die($retval); } ?> diff --git a/sapi/phpdbg/travis/ci.sh b/sapi/phpdbg/travis/ci.sh index 44d56a01ff..206b158b9b 100755 --- a/sapi/phpdbg/travis/ci.sh +++ b/sapi/phpdbg/travis/ci.sh @@ -1,9 +1,11 @@ #!/usr/bin/env sh git clone https://github.com/php/php-src -cd php-src/sapi +cd php-src +git checkout $PHP +cd sapi +rm -rf phpdbg 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/svnclean.bat b/svnclean.bat deleted file mode 100755 index 4c0118d671..0000000000 --- a/svnclean.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -cscript /nologo win32\build\cvsclean.js diff --git a/tests/basic/bug67198.phpt b/tests/basic/bug67198.phpt new file mode 100644 index 0000000000..9e2e224509 --- /dev/null +++ b/tests/basic/bug67198.phpt @@ -0,0 +1,42 @@ +--TEST-- +php://input is empty when enable_post_data_reading=Off +--INI-- +allow_url_fopen=1 +--SKIPIF-- +<?php +include __DIR__."/../../sapi/cli/tests/skipif.inc"; +?> +--FILE-- +<?php +require __DIR__."/../../sapi/cli/tests/php_cli_server.inc"; + +$code = +<<<'FL' + if(!ini_get('enable_post_data_reading')){ + if($_SERVER['REQUEST_METHOD']=='POST'){ + exit(file_get_contents('php://input')); + } + }else{ + exit('Please SET php.ini: enable_post_data_reading = Off'); + } +FL; + +$postdata = "PASS"; + +$opts = array('http' => + array( + 'method' => 'POST', + 'header' => 'Content-type: application/x-www-form-urlencoded', + 'content' => $postdata + ) +); + +$context = stream_context_create($opts); + +php_cli_server_start("exit(file_get_contents('php://input'));", false, "-d enable_post_data_reading=Off"); + +var_dump(file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS, false, $context)); +var_dump(file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS, false, $context)); +--EXPECT-- +string(4) "PASS" +string(4) "PASS" diff --git a/tests/classes/bug63462.phpt b/tests/classes/bug63462.phpt index dc5edbd5e1..f425c1526b 100644 --- a/tests/classes/bug63462.phpt +++ b/tests/classes/bug63462.phpt @@ -2,8 +2,6 @@ Test script to verify that magic methods should be called only once when accessing an unset property. --CREDITS-- Marco Pivetta <ocramius@gmail.com> ---XFAIL-- -Bug 63462 is not yet fixed --FILE-- <?php class Test { @@ -20,7 +18,7 @@ class Test { } function __get($name) { - echo '__get ' . $name . "\n"; + echo '__get ' . $name; return $this->$name; } @@ -54,13 +52,13 @@ $test->privateProperty = 'value'; --EXPECTF-- __get nonExisting -Notice: Undefined index: nonExisting in %__set__get_006.php on line %d +Notice: Undefined property: Test::$nonExisting in %sbug63462.php on line %d __get publicProperty -Notice: Undefined index: publicProperty in %__set__get_006.php on line %d +Notice: Undefined property: Test::$publicProperty in %sbug63462.php on line %d __get protectedProperty -Notice: Undefined index: protectedProperty in %__set__get_006.php on line %d +Notice: Undefined property: Test::$protectedProperty in %sbug63462.php on line %d __get privateProperty -Notice: Undefined index: privateProperty in %__set__get_006.php on line %d +Notice: Undefined property: Test::$privateProperty in %sbug63462.php on line %d __isset nonExisting __isset publicProperty __isset protectedProperty diff --git a/travis/compile.sh b/travis/compile.sh index 2b53099651..52748c6db5 100755 --- a/travis/compile.sh +++ b/travis/compile.sh @@ -1,6 +1,19 @@ #!/bin/bash -./buildconf +if [[ "$ENABLE_MAINTAINER_ZTS" == 1 ]]; then + TS="--enable-maintainer-zts"; +else + TS=""; +fi +if [[ "$ENABLE_DEBUG" == 1 ]]; then + DEBUG="--enable-debug"; +else + DEBUG=""; +fi +./buildconf --force ./configure --quiet \ +$DEBUG \ +$TS \ +--enable-fpm \ --with-pdo-mysql=mysqlnd \ --with-mysql=mysqlnd \ --with-mysqli=mysqlnd \ @@ -34,5 +47,14 @@ --enable-sockets \ --with-bz2 \ --with-openssl \ ---enable-bcmath +--with-gmp \ +--enable-bcmath \ +--enable-phpdbg \ +--enable-calendar \ +--enable-ftp \ +--with-pspell=/usr \ +--with-recode=/usr \ +--with-enchant=/usr \ +--enable-wddx \ +--enable-sysvmsg make --quiet @@ -1,10 +1,6 @@ #! /bin/sh -if test -d 'CVS'; then - ${MAKE:-make} -f build/build.mk cvsclean-work -elif test -d '.svn'; then - ${MAKE:-make} -f build/build.mk svnclean-work -elif test -d '.git'; then +if test -d '.git'; then ${MAKE:-make} -f build/build.mk gitclean-work else echo "Can't figure out your VCS, not cleaning." diff --git a/win32/build/cvsclean.js b/win32/build/cvsclean.js deleted file mode 100644 index c5f92a3883..0000000000 --- a/win32/build/cvsclean.js +++ /dev/null @@ -1,120 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 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: Wez Furlong <wez@thebrainroom.com> | - | Pierre A. Joye <pierre@php.net> | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ -// Cleans up files that do not belong in the repository - -var FSO = WScript.CreateObject("Scripting.FileSystemObject"); -var WshShell = WScript.CreateObject("WScript.Shell"); -var STDOUT = WScript.StdOut; - -/* svn propget svn:ignore dirname */ -function find_ignore(dirname) -{ - dirname = "" + dirname; - dirname_len = dirname.length; - - if (!FSO.FolderExists(dirname) || (dirname_len >= 4 && - dirname.substring(dirname_len - 4) == ".svn")) { - return; - } - - var f = FSO.GetFolder(dirname); - var fc = new Enumerator(f.SubFolders); - - for (; !fc.atEnd(); fc.moveNext()) { - find_ignore(fc.item()); - } - - kill_from_ignore(dirname); -} - -/* recursive remove using ignore props style wildcard matching; - * note that FSO.DeleteFolder and FSO.DeleteFile methods both - * accept wildcards, but that they are dangerous to use eg: - * "*.php" will match "*.phpt" */ -function rm_r(filename) -{ - if (FSO.FolderExists(filename)) { - var fc = new Enumerator(FSO.GetFolder(filename).SubFolders); - - for (; !fc.atEnd(); fc.moveNext()) { - rm_r(fc.item()); - } - - fc = new Enumerator(FSO.GetFolder(filename).Files); - - for (; !fc.atEnd(); fc.moveNext()) { - FSO.DeleteFile(fc.item(), true); - } - - FSO.DeleteFolder(filename, true); - } else if (FSO.FileExists(filename)) { - FSO.DeleteFile(filename, true); - } else { - /* we need to handle wildcards here */ - var foldername = FSO.GetParentFolderName(filename); - - if (foldername == "") - foldername = "."; - - var filename = FSO.GetFileName(filename); - - var retext = filename.replace(/\./g, '\\.'); - retext = '^' + retext.replace(/\*/g, '.*') + "$"; - var re = new RegExp(retext); - - var folder = FSO.GetFolder(foldername); - var fc = new Enumerator(folder.SubFolders); - for (; !fc.atEnd(); fc.moveNext()) { - - var item = FSO.GetFileName(fc.item()); - - if (item.match(re)) { - rm_r(fc.item()); - } - } - var fc = new Enumerator(folder.Files); - for (; !fc.atEnd(); fc.moveNext()) { - item = FSO.GetFileName(fc.item()); - - if (item.match(re)) { - FSO.DeleteFile(fc.item(), true); - } - } - } -} - -function kill_from_ignore(dirname) -{ - var l; - var e = WshShell.Exec("svn propget svn:ignore " + dirname); - var re = /^(config\.nice.*)|(\*)$/i; - - while (!e.StdOut.atEndOfStream) { - l = e.StdOut.ReadLine(); - if (l.length == 0 || re.test(l)) { - continue; - } - rm_r(dirname + l); - } - -} - -find_ignore("."); diff --git a/win32/build/libs_version.txt b/win32/build/libs_version.txt index a22823d0a9..0ea0067a62 100644 --- a/win32/build/libs_version.txt +++ b/win32/build/libs_version.txt @@ -13,4 +13,4 @@ libssh2-1.4.3 libtidy-20090406 libxslt-1.1.27 libxml-2.9.1 -openssl-1.0.1g +openssl-1.0.1h diff --git a/win32/build/mkdist.php b/win32/build/mkdist.php index 23d26c9c53..640e9b3bd7 100644 --- a/win32/build/mkdist.php +++ b/win32/build/mkdist.php @@ -246,7 +246,8 @@ foreach ($text_files as $src => $dest) { /* general other files */ $general_files = array( - "php.gif" => "php.gif", + "php.gif" => "php.gif", + "$GLOBALS[build_dir]\\deplister.exe" => "deplister.exe", ); foreach ($general_files as $src => $dest) { diff --git a/win32/build/svnclean.js b/win32/build/svnclean.js deleted file mode 100644 index c5f92a3883..0000000000 --- a/win32/build/svnclean.js +++ /dev/null @@ -1,120 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 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: Wez Furlong <wez@thebrainroom.com> | - | Pierre A. Joye <pierre@php.net> | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ -// Cleans up files that do not belong in the repository - -var FSO = WScript.CreateObject("Scripting.FileSystemObject"); -var WshShell = WScript.CreateObject("WScript.Shell"); -var STDOUT = WScript.StdOut; - -/* svn propget svn:ignore dirname */ -function find_ignore(dirname) -{ - dirname = "" + dirname; - dirname_len = dirname.length; - - if (!FSO.FolderExists(dirname) || (dirname_len >= 4 && - dirname.substring(dirname_len - 4) == ".svn")) { - return; - } - - var f = FSO.GetFolder(dirname); - var fc = new Enumerator(f.SubFolders); - - for (; !fc.atEnd(); fc.moveNext()) { - find_ignore(fc.item()); - } - - kill_from_ignore(dirname); -} - -/* recursive remove using ignore props style wildcard matching; - * note that FSO.DeleteFolder and FSO.DeleteFile methods both - * accept wildcards, but that they are dangerous to use eg: - * "*.php" will match "*.phpt" */ -function rm_r(filename) -{ - if (FSO.FolderExists(filename)) { - var fc = new Enumerator(FSO.GetFolder(filename).SubFolders); - - for (; !fc.atEnd(); fc.moveNext()) { - rm_r(fc.item()); - } - - fc = new Enumerator(FSO.GetFolder(filename).Files); - - for (; !fc.atEnd(); fc.moveNext()) { - FSO.DeleteFile(fc.item(), true); - } - - FSO.DeleteFolder(filename, true); - } else if (FSO.FileExists(filename)) { - FSO.DeleteFile(filename, true); - } else { - /* we need to handle wildcards here */ - var foldername = FSO.GetParentFolderName(filename); - - if (foldername == "") - foldername = "."; - - var filename = FSO.GetFileName(filename); - - var retext = filename.replace(/\./g, '\\.'); - retext = '^' + retext.replace(/\*/g, '.*') + "$"; - var re = new RegExp(retext); - - var folder = FSO.GetFolder(foldername); - var fc = new Enumerator(folder.SubFolders); - for (; !fc.atEnd(); fc.moveNext()) { - - var item = FSO.GetFileName(fc.item()); - - if (item.match(re)) { - rm_r(fc.item()); - } - } - var fc = new Enumerator(folder.Files); - for (; !fc.atEnd(); fc.moveNext()) { - item = FSO.GetFileName(fc.item()); - - if (item.match(re)) { - FSO.DeleteFile(fc.item(), true); - } - } - } -} - -function kill_from_ignore(dirname) -{ - var l; - var e = WshShell.Exec("svn propget svn:ignore " + dirname); - var re = /^(config\.nice.*)|(\*)$/i; - - while (!e.StdOut.atEndOfStream) { - l = e.StdOut.ReadLine(); - if (l.length == 0 || re.test(l)) { - continue; - } - rm_r(dirname + l); - } - -} - -find_ignore("."); diff --git a/win32/build/template.rc b/win32/build/template.rc index 13e92e9a3b..f36f2c041c 100644 --- a/win32/build/template.rc +++ b/win32/build/template.rc @@ -65,7 +65,7 @@ BEGIN #endif VALUE "FileVersion", EXT_VERSION VALUE "InternalName", INTERNAL_NAME - VALUE "LegalCopyright", "Copyright © 1997-2013 The PHP Group" + VALUE "LegalCopyright", "Copyright © 1997-2014 The PHP Group" VALUE "LegalTrademarks", "PHP" VALUE "OriginalFilename", FILE_NAME VALUE "ProductName", "PHP" |