mirror of
https://github.com/php/php-src.git
synced 2024-09-24 03:17:26 +00:00
initiate 5.4 branch
This commit is contained in:
commit
0f29950d9c
@ -73,6 +73,12 @@ PRIMARY MAINTAINER: Edin Kadribasic <edink@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: fpm
|
||||
PRIMARY MAINTAINER: Antony Dovgal <tony2001@php.net>, Jerome Loyet <fat@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.3.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: isapi
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
--------------------------------------------------------------------
|
||||
The PHP License, version 3.01
|
||||
Copyright (c) 1999 - 2009 The PHP Group. All rights reserved.
|
||||
Copyright (c) 1999 - 2010 The PHP Group. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
@ -5,24 +5,7 @@
|
||||
|
||||
lcov: lcov-html
|
||||
|
||||
lcov-test: all
|
||||
@echo "Running test suite"
|
||||
@find . -name \*.gcda -o -name \*.da -o -name \*.bbg? | xargs rm -f
|
||||
-@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
|
||||
NO_INTERACTION=1 \
|
||||
TEST_PHP_EXECUTABLE=$(PHP_EXECUTABLE) \
|
||||
TEST_PHP_SRCDIR=$(top_srcdir) \
|
||||
CC="$(CC)" \
|
||||
$(PHP_EXECUTABLE) -d 'open_basedir=' -d 'safe_mode=0' -d 'output_buffering=0' -d 'memory_limit=-1' $(top_srcdir)/run-tests.php -d 'extension_dir=modules/' -d `( . $(PHP_MODULES) ; echo extension=$$dlname)` tests/; \
|
||||
elif test ! -z "$(SAPI_CLI_PATH)" && test -x "$(SAPI_CLI_PATH)"; then \
|
||||
NO_INTERACTION=1 \
|
||||
TEST_PHP_EXECUTABLE=$(top_builddir)/$(SAPI_CLI_PATH) \
|
||||
TEST_PHP_SRCDIR=$(top_srcdir) \
|
||||
CC="$(CC)" \
|
||||
$(top_builddir)/$(SAPI_CLI_PATH) -d 'open_basedir=' -d 'safe_mode=0' -d 'output_buffering=0' -d 'memory_limit=-1' $(top_srcdir)/run-tests.php $(TESTS); \
|
||||
else \
|
||||
echo "ERROR: Cannot run tests without CLI sapi."; \
|
||||
fi
|
||||
lcov-test: lcov-clean-data test
|
||||
|
||||
php_lcov.info: lcov-test
|
||||
@echo "Generating data for $@"
|
||||
@ -77,3 +60,5 @@ lcov-clean:
|
||||
rm -rf lcov_data/
|
||||
rm -rf lcov_html/
|
||||
|
||||
lcov-clean-data:
|
||||
@find . -name \*.gcda -o -name \*.da -o -name \*.bbg? | xargs rm -f
|
||||
|
@ -13,6 +13,8 @@ all: $(all_targets)
|
||||
|
||||
build-modules: $(PHP_MODULES) $(PHP_ZEND_EX)
|
||||
|
||||
build-binaries: $(PHP_BINARIES)
|
||||
|
||||
libphp$(PHP_MAJOR_VERSION).la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
|
||||
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
|
||||
-@$(LIBTOOL) --silent --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1
|
||||
@ -35,6 +37,8 @@ install-sapi: $(OVERALL_TARGET)
|
||||
fi
|
||||
@$(INSTALL_IT)
|
||||
|
||||
install-binaries: build-binaries $(install_binary_targets)
|
||||
|
||||
install-modules: build-modules
|
||||
@test -d modules && \
|
||||
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR)
|
||||
@ -79,7 +83,7 @@ PHP_TEST_SHARED_EXTENSIONS = ` \
|
||||
. $$i; $(top_srcdir)/build/shtool echo -n -- " -d $(ZEND_EXT_TYPE)=$(top_builddir)/modules/$$dlname"; \
|
||||
done; \
|
||||
fi`
|
||||
PHP_DEPRECATED_DIRECTIVES_REGEX = '^(define_syslog_variables|register_(globals|long_arrays)?|safe_mode|magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?)[\t\ ]*='
|
||||
PHP_DEPRECATED_DIRECTIVES_REGEX = '^(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?)[\t\ ]*='
|
||||
|
||||
test: all
|
||||
-@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
|
||||
@ -98,6 +102,7 @@ test: all
|
||||
TEST_PHP_SRCDIR=$(top_srcdir) \
|
||||
CC="$(CC)" \
|
||||
$(PHP_EXECUTABLE) -n -c $(top_builddir)/tmp-php.ini $(PHP_TEST_SETTINGS) $(top_srcdir)/run-tests.php -n -c $(top_builddir)/tmp-php.ini -d extension_dir=$(top_builddir)/modules/ $(PHP_TEST_SHARED_EXTENSIONS) $(TESTS); \
|
||||
rm $(top_builddir)/tmp-php.ini; \
|
||||
else \
|
||||
echo "ERROR: Cannot run tests without CLI sapi."; \
|
||||
fi
|
||||
|
@ -20,18 +20,18 @@ API adjustment to the old output control code:
|
||||
|
||||
Starting an internal handler whithout context:
|
||||
// php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase TSRMLS_CC);
|
||||
php_output_start_internal(handler_name_zval, my_php_output_handler_func_t, chunk_size, flags TSRMLS_CC);
|
||||
php_output_start_internal(handler_name, handler_name_len, my_php_output_handler_func_t, chunk_size, flags TSRMLS_CC);
|
||||
|
||||
Starting an internal handler with context:
|
||||
// not possible with old API
|
||||
php_output_handler *h;
|
||||
h = php_output_handler_create_internal(handler_name_zval, my_php_output_handler_context_func_t, chunk_size, flags TSRMLS_CC);
|
||||
h = php_output_handler_create_internal(handler_name, handler_name_len, my_php_output_handler_context_func_t, chunk_size, flags TSRMLS_CC);
|
||||
php_output_handler_set_context(h, my_context, my_context_dtor);
|
||||
php_output_handler_start(h TSRMLS_CC);
|
||||
|
||||
Testing whether a certain output handler has already been started:
|
||||
// php_ob_handler_used("output handler name" TSRMLS_CC);
|
||||
php_output_handler_started(handler_name_zval TSRMLS_CC);
|
||||
php_output_handler_started(handler_name, handler_name_len TSRMLS_CC);
|
||||
|
||||
Flushing one output buffer:
|
||||
// php_ob_end_buffer(1, 1 TSRMLS_CC);
|
||||
@ -79,15 +79,15 @@ API adjustment to the old output control code:
|
||||
|
||||
Issue a warning because of an output handler conflict:
|
||||
// php_ob_init_conflict("to be started handler name", "to be tested if already started handler name" TSRMLS_CC);
|
||||
php_output_handler_conflict(new_handler_name_zval, set_handler_name_zval TSRMLS_CC);
|
||||
php_output_handler_conflict(new_handler_name, new_handler_name_len, set_handler_name, set_handler_name_len TSRMLS_CC);
|
||||
|
||||
Registering a conflict checking function, which will be checked prior starting the handler:
|
||||
// not possible with old API, unless hardcoding into output.c
|
||||
php_output_handler_conflict_register(handler_name_zval, my_php_output_handler_conflict_check_t TSRMLS_CC);
|
||||
php_output_handler_conflict_register(handler_name, handler_name_len, my_php_output_handler_conflict_check_t TSRMLS_CC);
|
||||
|
||||
Registering a reverse conflict checking function, which will be checked prior starting the specified foreign handler:
|
||||
// not possible with old API
|
||||
php_output_handler_reverse_conflict_register(foreign_handler_name_zval, my_php_output_handler_conflict_check_t TSRMLS_CC);
|
||||
php_output_handler_reverse_conflict_register(foreign_handler_name, foreign_handler_name_len, my_php_output_handler_conflict_check_t TSRMLS_CC);
|
||||
|
||||
Facilitating a context from within an output handler callable with ob_start():
|
||||
// not possible with old API
|
||||
|
57
README.QNX
57
README.QNX
@ -1,57 +0,0 @@
|
||||
QNX4 Installation Notes
|
||||
-----------------------
|
||||
|
||||
NOTE: General installation instructions are in the INSTALL file
|
||||
|
||||
|
||||
1. To compile and test PHP3 you have to grab, compile and install:
|
||||
- GNU dbm library or another db library;
|
||||
- GNU bison (1.25 or later; 1.25 tested);
|
||||
- GNU flex (any version supporting -o and -P options; 2.5.4 tested);
|
||||
- GNU diffutils (any version supporting -w option; 2.7 tested);
|
||||
|
||||
2. To use CVS version you may need also:
|
||||
- GNU CVS (1.9 tested);
|
||||
- GNU autoconf (2.12 tested);
|
||||
- GNU m4 (1.3 or later preferable; 1.4 tested);
|
||||
|
||||
3. To run configure define -lunix in command line:
|
||||
LDFLAGS=-lunix ./configure
|
||||
|
||||
4. To use Sybase SQL Anywhere define ODBC_QNX and CUSTOM_ODBC_LIBS in
|
||||
command line and run configure with --with-custom-odbc:
|
||||
CFLAGS=-DODBC_QNX LDFLAGS=-lunix CUSTOM_ODBC_LIBS="-ldblib -lodbc" ./configure --with-custom-odbc=/usr/lib/sqlany50
|
||||
If you have SQL Anywhere version 5.5.00, then you have to add
|
||||
CFLAGS=-DSQLANY_BUG
|
||||
to workaround its SQLFreeEnv() bug. Other versions has not been tested,
|
||||
so try without this flag first.
|
||||
|
||||
5. To build the Apache module, you may have to hardcode an include path for
|
||||
alloc.h in your Apache base directory:
|
||||
- APACHE_DIRECTORY/src/httpd.h:
|
||||
change #include "alloc.h"
|
||||
to #include "APACHE_DIRECTORY/src/alloc.h"
|
||||
Unless you want to use system regex library, you have to hardcode also
|
||||
a path to regex.h:
|
||||
- APACHE_DIRECTORY/src/conf.h:
|
||||
change #include <regex.h>
|
||||
to #include "APACHE_DIRECTORY/src/regex/regex.h"
|
||||
I don't know so far why this required for QNX, may be it is Watcom
|
||||
compiler problem.
|
||||
|
||||
If you building Apache module with SQL Anywhere support, you'll get
|
||||
symbol conflict with BOOL. It is defined in Apache (httpd.h) and in
|
||||
SQL Anywhere (odbc.h). This has nothing to do with PHP, so you have to
|
||||
fix it yourself someway.
|
||||
|
||||
6. With above precautions, it should compile as is and pass regression
|
||||
tests completely:
|
||||
make
|
||||
make check
|
||||
make install
|
||||
|
||||
Don't bother me unless you really sure you made that all but it
|
||||
still doesn't work.
|
||||
|
||||
June 28, 1998
|
||||
Igor Kovalenko -- owl@infomarket.ru
|
@ -20,12 +20,18 @@ 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. Moving extensions from/to PECL requires root level access to the CVS server.
|
||||
Contact systems@php.net to get this taken care of.
|
||||
6. Moving extensions from/to PECL requires write acces to the destination.
|
||||
Most developers should have this.
|
||||
|
||||
Moving extensions from php-src to PECL
|
||||
- Filesystem: cp -r php-src/ext/foo pecl/foo
|
||||
- cvs rm php-src/ext/foo
|
||||
- Checkout the pecl directory, most likely you want a sparse-root checkout
|
||||
svn co --depth=empty https://svn.php.net/repository/pecl
|
||||
- Create an directory for the extension incl. branch and tag structure,
|
||||
no trunk at this point and commit this to svn
|
||||
cd pecl; mkdir foo foo/tags foo/branches; svn add foo; svn commit
|
||||
- Move the extension from php-src to the new location
|
||||
svn mv https://svn.php.net/repository/php/php-src/trunk/ext/foo \
|
||||
https://svn.php.net/repository/pecl/foo/trunk
|
||||
|
||||
If the extension is still usable or not dead, in cooperation with the extension
|
||||
maintainers if any:
|
||||
@ -33,25 +39,23 @@ maintainers if any:
|
||||
- create the package.xml, commit
|
||||
- release the package
|
||||
|
||||
Moving extensions from PECL to php-src
|
||||
- Filesystem: cp -r pecl/foo php-src/ext/foo
|
||||
OR depending on the wishes from the PECL extension maintainer.
|
||||
- Filesystem: ln -s pecl/foo php-src/ext/foo
|
||||
For Moving extensions from PECL to php-src the svn mv has to be tone the other
|
||||
way round.
|
||||
|
||||
Rolling a non stable release (alpha/beta/RC)
|
||||
--------------------------------------------
|
||||
|
||||
1. Check windows snapshot builder logs (http://snaps.php.net/win32/snapshot-STABLE.log f.e.)
|
||||
|
||||
2. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``.
|
||||
Do not use abbreviations for alpha and beta.
|
||||
|
||||
3. Commit those changes
|
||||
|
||||
4. run the "scripts/dev/credits" script in php-src and commit the changes in the
|
||||
2. run the "scripts/dev/credits" script in php-src and commit the changes in the
|
||||
credits files in ext/standard.
|
||||
|
||||
5. tag the repository with the version f.e. "``cvs tag php_4_4_1RC1``"
|
||||
3. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``.
|
||||
Do not use abbreviations for alpha and beta.
|
||||
|
||||
4. Commit those changes and note the revision id.
|
||||
|
||||
5. tag the repository with the version. To do the tag in a fast way do a svn copy on the server using full URLs. You should use the revision id from the above commit to prevent mistakes in case there was a commit in between. f.e. "``svn cp https://svn.php.net/repository/php/php-src/branches/PHP_5_3@308399 https://svn.php.net/repository/php/php-src/tags/php_5_3_6RC1``"
|
||||
(of course, you need to change that to the version you're rolling an RC for).
|
||||
|
||||
6. Bump up the version numbers in ``main/php_version.h``, ``configure.in``
|
||||
@ -65,7 +69,7 @@ correctly work.
|
||||
8. Log in onto the snaps box and go into the correct tree (f.e. the PHP_4_4
|
||||
branch if you're rolling 4.4.x releases).
|
||||
|
||||
9. You do not have to update the tree, but of course you can with "``cvs up -dP``".
|
||||
9. You do not have to update the tree, but of course you can with "``svn up``".
|
||||
|
||||
10. run: ``./makedist php 4.4.1RC1``, this will export the tree, create configure
|
||||
and build two tarballs (one gz and one bz2).
|
||||
@ -100,7 +104,7 @@ Derick) run the following commands for you:
|
||||
|
||||
``sudo -u ezmlm ezmlm-sub ~ezmlm/primary-qa-tester/mod moderator-email-address``
|
||||
|
||||
3. Update the MD5 sums in ``web/qa/trunk/include/rc-md5sums.txt`` (no empty lines).
|
||||
3. Update the MD5 sums in ``web/qa/trunk/include/rc-md5sums.txt`` (no empty lines, ordered by filename, odler version number first, .bz2 before .gz).
|
||||
|
||||
4. Update in ``web/qa/trunk/include/release-qa.php`` constants with the new RC and
|
||||
commit this.
|
||||
@ -111,10 +115,9 @@ commit this.
|
||||
|
||||
c. ``$RELEASE_PROCESS`` = array(4 => true, 5 => true)
|
||||
|
||||
1. Update in ``php-bugs/trunk/include/functions.inc`` the ``show_version_option``
|
||||
function to include the new RC and commit.
|
||||
1. Update in ``web/php-bugs/trunk/include/php_versions.php`` to include the new RC and commit.
|
||||
|
||||
2. Update ``phpweb/include/version.inc`` (x=major version number)
|
||||
2. Update ``web/php/trunk/include/version.inc`` (x=major version number)
|
||||
|
||||
a. ``$PHP_x_RC`` = "5.3.0RC1"
|
||||
|
||||
@ -122,7 +125,7 @@ function to include the new RC and commit.
|
||||
|
||||
3. Commit those changes:
|
||||
|
||||
a. ``cvs commit include/version.inc include/releases.inc``
|
||||
a. ``svn commit web/qa/trunk web/php-bugs/trunk web/php/trunk``
|
||||
|
||||
4. For the first RC, write the doc team (phpdoc@lists.php.net) about updating the
|
||||
INSTALL and win32/install.txt files which are generated from the PHP manual sources.
|
||||
|
@ -1,74 +1,134 @@
|
||||
Submitting Patches to PHP
|
||||
=========================
|
||||
Submitting Enhancements and Patches to PHP
|
||||
==========================================
|
||||
|
||||
This document describes how to submit a patch for PHP. Creating a
|
||||
patch for PHP is easy!
|
||||
This document describes how to submit an enhancement or patch for PHP.
|
||||
It's easy!
|
||||
|
||||
You don't need any login accounts or special access to download,
|
||||
build, debug and begin submitting PHP code, tests or documentation for
|
||||
inclusion in PHP. Once you've followed this README and had several
|
||||
patches accepted, PHP commit privileges are often quickly granted.
|
||||
build, debug and begin submitting PHP, PECL or PEAR code, tests or
|
||||
documentation. Once you've followed this README and had several
|
||||
patches accepted, commit privileges are often quickly granted.
|
||||
|
||||
An excellent article to read first is:
|
||||
http://phpadvent.org/2008/less-whining-more-coding-by-elizabeth-smith
|
||||
|
||||
|
||||
Prework
|
||||
-------
|
||||
If you are fixing broken functionality then create a bug or identify
|
||||
an existing bug at http://bugs.php.net/. This can be used to track
|
||||
the patch progress and prevent your changes getting lost in the PHP
|
||||
mail archives.
|
||||
Online Forums
|
||||
-------------
|
||||
There are several IRC channels where PHP developers are often
|
||||
available to discuss questions. They include #php.pecl, #php.doc and
|
||||
#pear on the EFNet network and #php-dev-win on FreeNode.
|
||||
|
||||
If your code change is large, then first discuss it with the extension
|
||||
maintainer and/or a development mail list. Extension maintainers can
|
||||
be found in the EXTENSIONS file in the PHP source. Use the
|
||||
internals@lists.php.net mail list to discuss changes to the base PHP
|
||||
code. Use pecl-dev@lists.php.net for changes to code that is only
|
||||
available from PECL (http://pecl.php.net/). Use pear-dev@lists.php.net
|
||||
for PEAR modules (http://pear.php.net/). Use phpdoc@lists.php.net for
|
||||
PHP documentation questions. Mail list subscription is explained on
|
||||
http://www.php.net/mailing-lists.php.
|
||||
|
||||
If a PHP or PECL patch affects user functionality or makes significant
|
||||
internal changes then create a simple Request For Comment (RFC) page
|
||||
on http://wiki.php.net/rfc before starting discussion. This RFC can be
|
||||
used for initial discussion and later for documentation. Wiki accounts
|
||||
can be requested on http://wiki.php.net/start?do=register
|
||||
PHP Patches
|
||||
-----------
|
||||
If you are fixing broken functionality in PHP C source code first
|
||||
create a bug or identify an existing bug at http://bugs.php.net/. A
|
||||
bug can be used to track the patch progress and prevent your changes
|
||||
getting lost in the PHP mail archives.
|
||||
|
||||
Online information on PHP internal C functions is at
|
||||
http://www.php.net/internals, though this is considered
|
||||
incomplete. Various external resources can be found on the web. A
|
||||
standard reference is the book "Extending and Embedding PHP" by Sara
|
||||
If your change is large then create a Request For Comment (RFC) page
|
||||
on http://wiki.php.net/rfc, discuss it with the extension maintainer,
|
||||
and discuss it on the development mail list internals@lists.php.net.
|
||||
RFC Wiki accounts can be requested on
|
||||
http://wiki.php.net/start?do=register. PHP extension maintainers can
|
||||
be found in the EXTENSIONS file in the PHP source. Mail list
|
||||
subscription is explained on http://www.php.net/mailing-lists.php.
|
||||
|
||||
Information on PHP internal C functions is at
|
||||
http://www.php.net/internals, though this is considered incomplete.
|
||||
Various external resources can be found on the web. A standard
|
||||
printed reference is the book "Extending and Embedding PHP" by Sara
|
||||
Golemon.
|
||||
|
||||
Information on contributing to PEAR is available at
|
||||
http://pear.php.net/manual/en/guide-developers.php
|
||||
Attach the patch to the PHP bug and consider sending a notification
|
||||
email about the change to internals@lists.php.net. Also CC the
|
||||
extension maintainer. Explain what has been changed by your patch.
|
||||
Test scripts should be included.
|
||||
|
||||
Please make the mail subject prefix "[PATCH]". If attaching a patch,
|
||||
ensure it has a file extension of ".txt". This is because only MIME
|
||||
attachments of type 'text/*' are accepted.
|
||||
|
||||
|
||||
PHP Documentation Patches
|
||||
-------------------------
|
||||
If you are fixing incorrect PHP documentation first create a bug or
|
||||
identify an existing bug at http://bugs.php.net/. A bug can be used
|
||||
to track the patch progress and prevent your changes getting lost in
|
||||
the PHP mail archives.
|
||||
|
||||
If your change is large, then first discuss it with the mail list
|
||||
phpdoc@lists.php.net. Subscription is explained on
|
||||
http://www.php.net/mailing-lists.php.
|
||||
|
||||
Information on contributing to PHP documentation is at
|
||||
http://php.net/dochowto and http://wiki.php.net/doc/howto
|
||||
|
||||
There are several IRC channels where PHP developers are often
|
||||
available to discuss questions. They include #php.pecl and #php.doc
|
||||
on the EFNet network and #php-dev-win on FreeNode.
|
||||
Attach the patch to the PHP bug and consider sending a notification
|
||||
email about the change to phpdoc@lists.php.net. Explain what has been
|
||||
fixed/added/changed by your patch.
|
||||
|
||||
Please make the mail subject prefix "[PATCH]". Include the bug id(s)
|
||||
which can be closed by your patch. If attaching a patch, ensure it
|
||||
has a file extension of ".txt". This is because only MIME attachments
|
||||
of type 'text/*' are accepted.
|
||||
|
||||
|
||||
How to create your patch
|
||||
------------------------
|
||||
PHP uses Subversion (SVN) for revision control. Read
|
||||
PECL Extension Patches: http://pecl.php.net/
|
||||
--------------------------------------------
|
||||
If you are fixing broken functionality in a PECL extension then create
|
||||
a bug or identify an existing bug at http://pecl.php.net/bugs/. A bug
|
||||
can be used to track the patch progress and prevent your changes
|
||||
getting lost in the PHP mail archives.
|
||||
|
||||
If your change is large then create a Request For Comment (RFC) page
|
||||
on http://wiki.php.net/rfc, discuss it with the extension maintainer,
|
||||
and discuss it on the development mail list pecl-dev@lists.php.net.
|
||||
PECL mail list subscription is explained on
|
||||
http://pecl.php.net/support.php. RFC Wiki accounts can be requested
|
||||
on http://wiki.php.net/start?do=register
|
||||
|
||||
Information on PHP internal C functions is at
|
||||
http://www.php.net/internals, though this is considered incomplete.
|
||||
Various external resources can be found on the web. A standard
|
||||
printed reference is the book "Extending and Embedding PHP" by Sara
|
||||
Golemon.
|
||||
|
||||
Update any open bugs and add a link to the source of your patch. Send
|
||||
the patch or pointer to the bug to pecl-dev@lists.php.net. Also CC
|
||||
the extension maintainer. Explain what has been changed by your
|
||||
patch. Test scripts should be included.
|
||||
|
||||
Please make the mail subject prefix "[PATCH] ...". Include the patch
|
||||
as an attachment with a file extension of ".txt". This is because
|
||||
only MIME attachments of type 'text/*' are accepted.
|
||||
|
||||
|
||||
PEAR Package Patches: http://pear.php.net/
|
||||
------------------------------------------
|
||||
Information on contributing to PEAR is available at
|
||||
http://pear.php.net/manual/en/developers-newmaint.php and
|
||||
http://pear.php.net/manual/en/guide-developers.php
|
||||
|
||||
|
||||
How to create your PHP, PHP Documentation or PECL patch
|
||||
-------------------------------------------------------
|
||||
PHP and PECL use Subversion (SVN) for revision control. Read
|
||||
http://www.php.net/svn.php for help on using SVN to get and build PHP
|
||||
source code. We recommend using a Sparse Directory checkout described
|
||||
in http://wiki.php.net/vcs/svnfaq. If you are new to SVN, read
|
||||
source code. We recommend using a Sparse Directory checkout described
|
||||
in http://wiki.php.net/vcs/svnfaq. If you are new to SVN, read
|
||||
http://svnbook.red-bean.com.
|
||||
|
||||
Generally we ask that patches work on the current stable PHP
|
||||
development branch and on "trunk".
|
||||
Generally we ask that bug fix patches work on the current stable PHP
|
||||
development branches and on "trunk". New PHP features only need to
|
||||
work on "trunk".
|
||||
|
||||
Read CODING_STANDARDS before you start working.
|
||||
|
||||
After modifying the source see README.TESTING and
|
||||
http://qa.php.net/write-test.php for how to test. Submitting test
|
||||
scripts helps us to understand what functionality has changed. It is
|
||||
http://qa.php.net/write-test.php for how to test. Submitting test
|
||||
scripts helps us to understand what functionality has changed. It is
|
||||
important for the stability and maintainability of PHP that tests are
|
||||
comprehensive.
|
||||
|
||||
@ -80,73 +140,43 @@ For ease of review and later troubleshooting, submit individual
|
||||
patches for each bug or feature.
|
||||
|
||||
|
||||
Checklist for submitting your patch
|
||||
-----------------------------------
|
||||
Checklist for submitting your PHP or PECL code patch
|
||||
----------------------------------------------------
|
||||
- Update SVN source just before running your final 'diff' and
|
||||
before testing.
|
||||
- Add in-line comments and/or have external documentation ready.
|
||||
Use only "/* */" style comments, not "//".
|
||||
- Create test scripts for use with "make test".
|
||||
- Run "make test" to check your patch doesn't break other features.
|
||||
- Rebuild PHP with --enable-debug (which will show some kinds of
|
||||
memory errors) and check the PHP and web server error logs after
|
||||
running the PHP tests.
|
||||
- Rebuild PHP with --enable-maintainer-zts to check your patch compiles
|
||||
on multi-threaded web servers.
|
||||
- Create test scripts for use with "make test".
|
||||
- Add in-line comments and/or have external documentation ready.
|
||||
running your PHP tests.
|
||||
- Rebuild PHP with --enable-maintainer-zts to check your patch
|
||||
compiles on multi-threaded web servers.
|
||||
- Review the patch once more just before submitting it.
|
||||
|
||||
|
||||
Where to send your patch
|
||||
------------------------
|
||||
If you are patching PHP C source then email the patch to
|
||||
internals@lists.php.net
|
||||
|
||||
If you patching a PECL extension then send the patch to
|
||||
pecl-dev@lists.php.net
|
||||
|
||||
If you are patching PEAR then send the patch to
|
||||
pear-dev@lists.php.net
|
||||
|
||||
If you are patching PHP's documentation then send the patch to
|
||||
phpdoc@lists.php.net
|
||||
|
||||
The mail can be CC'd to the extension maintainer (see EXTENSIONS).
|
||||
|
||||
Please make the subject prefix "[PATCH]", for example "[PATCH] Fix
|
||||
return value of all array functions"
|
||||
|
||||
Include the patch as an attachment with a file extension of ".txt".
|
||||
This is because only MIME attachments of type 'text/*' are accepted.
|
||||
|
||||
Explain what has been fixed/added/changed by your patch. Test scripts
|
||||
should be included in the email.
|
||||
|
||||
Include the bug id(s) which can be closed by your patch.
|
||||
|
||||
Finally, update any open bugs and add a link to the source of your
|
||||
patch.
|
||||
|
||||
|
||||
What happens after you submit your patch
|
||||
----------------------------------------
|
||||
What happens after submitting your PHP, PHP Documentation or PECL patch
|
||||
-----------------------------------------------------------------------
|
||||
If your patch is easy to review and obviously has no side-effects,
|
||||
it might be committed relatively quickly.
|
||||
|
||||
Because PHP is a volunteer-driven effort more complex patches will
|
||||
require patience on your side. If you do not receive feedback in a few
|
||||
days, consider resubmitting the patch. Before doing this think about
|
||||
these questions:
|
||||
require patience on your side. If you do not receive feedback in a
|
||||
few days, consider resubmitting the patch. Before doing this think
|
||||
about these questions:
|
||||
|
||||
- Did I send the patch to the right mail list?
|
||||
- Did I review the mail list archives to see if these kind of
|
||||
changes had been discussed before?
|
||||
- Did I explain my patch clearly?
|
||||
- Is my patch too hard to review? Because of which factors?
|
||||
- Are there any unwanted white space changes?
|
||||
- Is my patch too hard to review? Because of what factors?
|
||||
|
||||
|
||||
What happens when your patch is applied
|
||||
---------------------------------------
|
||||
Your name will be included in the SVN commit log. If your patch
|
||||
affects end users, a brief description and your name might be added to
|
||||
the NEWS file.
|
||||
What happens when your PHP or PECL patch is applied
|
||||
---------------------------------------------------
|
||||
Your name will likely be included in the SVN commit log. If your
|
||||
patch affects end users, a brief description and your name might be
|
||||
added to the NEWS file.
|
||||
|
||||
Thank you for patching PHP!
|
||||
|
@ -19,9 +19,7 @@ A simple implementation might look like the following. This stores the
|
||||
original raw user data and adds a my_get_raw() function while the normal
|
||||
$_POST, $_GET and $_COOKIE arrays are only populated with stripped
|
||||
data. In this simple example all I am doing is calling strip_tags() on
|
||||
the data. If register_globals is turned on, the default globals that
|
||||
are created will be stripped ($foo) while a $RAW_foo is created with the
|
||||
original user input.
|
||||
the data.
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
|
||||
zval *post_array;
|
||||
@ -155,8 +153,6 @@ PHP_FUNCTION(my_get_raw)
|
||||
int var_len;
|
||||
zval **tmp;
|
||||
zval *array_ptr = NULL;
|
||||
HashTable *hash_ptr;
|
||||
char *raw_var;
|
||||
|
||||
if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
|
||||
return;
|
||||
@ -174,23 +170,15 @@ PHP_FUNCTION(my_get_raw)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!array_ptr) RETURN_FALSE;
|
||||
if(!array_ptr) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* I'm changing the variable name here because when running with register_globals on,
|
||||
* the variable will end up in the global symbol table
|
||||
*/
|
||||
raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
|
||||
strcpy(raw_var, "RAW_");
|
||||
strlcat(raw_var,var,var_len+5);
|
||||
hash_ptr = HASH_OF(array_ptr);
|
||||
|
||||
if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
|
||||
if(zend_hash_find(HASH_OF(array_ptr), var, var_len+5, (void **)&tmp) == SUCCESS) {
|
||||
*return_value = **tmp;
|
||||
zval_copy_ctor(return_value);
|
||||
} else {
|
||||
RETVAL_FALSE;
|
||||
}
|
||||
efree(raw_var);
|
||||
}
|
||||
|
||||
|
137
TODO
137
TODO
@ -1,137 +0,0 @@
|
||||
Things to do or at least think about doing in the future. Name in
|
||||
parenthesis means that person has taken on this project.
|
||||
|
||||
Zend
|
||||
----
|
||||
* Allow foreach ($array as $k => list($a, $b)) syntax for multi
|
||||
dimensional arrays.
|
||||
* Look at replacing c-lib call tolower().
|
||||
* Make hash API functions work with HASH_OF() to save time.
|
||||
* Native large number support (probably with GNU GMP)
|
||||
* Const'ify APIs. Right now, many functions leave parameters untouched,
|
||||
but don't declare those as const. This makes interaction with other
|
||||
interfaces difficult which pass const parameters to us.
|
||||
* Look at making zend_constant value member be a zval* instead of zval. (Andi)
|
||||
* Implement inheritance rules for type hints. (Marcus)
|
||||
|
||||
global
|
||||
------
|
||||
* Make sure that all ZTS globals get destructed. Most ts_allocate_id()
|
||||
calls should have a dtor entry.
|
||||
* on some platforms unimplemented function will just do nothing
|
||||
(e.g. symlink) they should print a warning or not even be defined!
|
||||
(DONE ?)
|
||||
* --enable-all in configure. (--enable-shared=max ...)
|
||||
* make configure print out a summary when it's done (like XEmacs)
|
||||
* replace standard functions which work on static data with
|
||||
reentrancy-safe functions (DONE?).
|
||||
* make SAPI conform to CGI/1.1. Currently, all SAPI modules
|
||||
define REMOTE_ADDR etc. themselves and reach only various level
|
||||
of compliance.
|
||||
* see what functions might need to be changed to use HashPosition, so
|
||||
that the internal array pointer is not affected.
|
||||
* Move most extensions and PEAR packages out of the PHP CVS tree,
|
||||
include them again during release packaging.
|
||||
|
||||
Other
|
||||
* use thread-safe resolver functions (either require BIND 8 or adns).
|
||||
* implement javadoc based function docs template system.
|
||||
* provide optional IPv6 support (seems to be done?).
|
||||
* find a better way to implement script timeouts. SIGVTALRM is used
|
||||
by some POSIX threads implementations (i.e. OpenBSD) and is not
|
||||
available in ZTS mode.
|
||||
* Implement flush feature suitable for nested output buffers.
|
||||
|
||||
Streams
|
||||
-------
|
||||
* Route filestat.c through the wrapper layer; isolate the statcache code
|
||||
so that it is independent of php functions and can be applied to any
|
||||
stream/path.
|
||||
* Implement generalized connection pool for stated protocols such as
|
||||
ftp and http/1.1 (using keep-alive) to avoid having to negotiate
|
||||
new command/request stream for each subsequent call; Possibly store
|
||||
resources in contexts (creating a default context if necessary) to
|
||||
allow segmentation of connection pools.
|
||||
* Add a method to take ownership of the memory buffer in memory streams so
|
||||
that generating string values for zvals doesn't require an estrdup.
|
||||
* bundle and use curl lib for fopen wrapper.
|
||||
|
||||
documentation
|
||||
-------------
|
||||
* Add remarks in the documentation which functions are not implemented
|
||||
on win32.
|
||||
* Add remarks in the documentation which functions are not binary-safe.
|
||||
* Update curl documentation (DONE?)
|
||||
* Add developer documentation.
|
||||
* Add detailed documentation for Java extension.
|
||||
|
||||
ext/curl
|
||||
--------
|
||||
* Have a warning scheme for when people use unsupported features.
|
||||
|
||||
ext/oci8
|
||||
--------
|
||||
* All OCIFetch*() functions should return 0 for no more data and false on
|
||||
error.
|
||||
* Have a flag that trims trailing spaces from CHAR fields on retrieval.
|
||||
* Make allow_call_time_pass_reference=Off working.
|
||||
* For additional todo information, see oci8.c, in ext/oci8
|
||||
|
||||
ext/odbc
|
||||
--------
|
||||
For PHP 4.3.0:
|
||||
* update all php_error calls to php_error_docref where valid
|
||||
* integrate EXPERIMENTAL ODBC update for use in PHP 5.0, use for
|
||||
testing purposes only.
|
||||
|
||||
For PHP 5.0.0
|
||||
* Activate EXPERIMENTAL ODBC codebase update
|
||||
|
||||
ext/pcre
|
||||
--------
|
||||
* Allow user to set PCRE_NOTEMPTY, PCRE_ANCHORED at execution time, maybe
|
||||
|
||||
ext/pcntl
|
||||
---------
|
||||
* Change internal callback handler to use TICKS
|
||||
* Remove all zend_extension code
|
||||
* Add object callback support to pcntl_signal()
|
||||
|
||||
ext/session
|
||||
-----------
|
||||
For PHP 4.3.0:
|
||||
* session_abort() to abort session. ie: Do not save session data.
|
||||
* Allow unset($_SESSION) or unset($HTTP_SESSION_VARS) to unset
|
||||
session vars regardless of register_globals setting.
|
||||
|
||||
Other:
|
||||
* Maybe implement finer-grained session variables that could be
|
||||
locked individually.
|
||||
* Write a network-transparent storage back-end with fallover
|
||||
facilities
|
||||
* Provide a callback facility which is executed upon encountering
|
||||
an unknown class name during deserialization
|
||||
|
||||
ext/standard
|
||||
------------
|
||||
* Add a version number to data serialized via serialize().
|
||||
* Possibly modify parsing of GPC data to automatically create arrays if
|
||||
variable name is seen more than once.
|
||||
* Implement regex-cache for url-functions.
|
||||
* Move socket related functions to fsock.c.
|
||||
|
||||
ext/wddx
|
||||
--------
|
||||
* See if we can support the remaining data types:
|
||||
binary
|
||||
|
||||
http://www.wddx.org/WDDX_SDK_10a/7__References/WDDX_DTD.htm
|
||||
(Andrei)
|
||||
|
||||
* implement wddx_packet_as_javascript(). (Andrei)
|
||||
|
||||
other cool stuff
|
||||
----------------
|
||||
* PVM extension
|
||||
|
||||
vim:et:sw=4:ts=4
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| Thread Safe Resource Manager |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1999-2010, Andi Gutmans, Sascha Schumann, Zeev Suraski |
|
||||
| Copyright (c) 1999-2011, Andi Gutmans, Sascha Schumann, Zeev Suraski |
|
||||
| This source file is subject to the TSRM license, that is bundled |
|
||||
| with this package in the file LICENSE |
|
||||
+----------------------------------------------------------------------+
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| Thread Safe Resource Manager |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1999-2010, Andi Gutmans, Sascha Schumann, Zeev Suraski |
|
||||
| Copyright (c) 1999-2011, Andi Gutmans, Sascha Schumann, Zeev Suraski |
|
||||
| This source file is subject to the TSRM license, that is bundled |
|
||||
| with this package in the file LICENSE |
|
||||
+----------------------------------------------------------------------+
|
||||
|
@ -1,10 +1,5 @@
|
||||
// vim:ft=javascript
|
||||
// $Id$
|
||||
|
||||
if (CHECK_HEADER_ADD_INCLUDE("NewAPIs.h", "CFLAGS_PHP", php_usual_include_suspects)) {
|
||||
// Need to add the flag directly, since TSRM doesn't include the config
|
||||
// header
|
||||
ADD_FLAG("CFLAGS_PHP", "/DHAVE_NEWAPIS_H=1");
|
||||
}
|
||||
ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c tsrm_win32.c");
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
| Copyright (c) 1997-2011 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 |
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
| Copyright (c) 1997-2011 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 |
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
| Copyright (c) 1997-2011 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,6 +14,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Sascha Schumann <sascha@schumann.cx> |
|
||||
| Pierre Joye <pierre@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
@ -38,6 +39,18 @@
|
||||
# ifndef IO_REPARSE_TAG_SYMLINK
|
||||
# define IO_REPARSE_TAG_SYMLINK 0xA000000C
|
||||
# endif
|
||||
|
||||
# ifndef VOLUME_NAME_NT
|
||||
# define VOLUME_NAME_NT 0x2
|
||||
# endif
|
||||
|
||||
# ifndef VOLUME_NAME_DOS
|
||||
# define VOLUME_NAME_DOS 0x0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef S_IFLNK
|
||||
# define S_IFLNK 0120000
|
||||
#endif
|
||||
|
||||
#ifdef NETWARE
|
||||
@ -83,14 +96,14 @@ cwd_state main_cwd_state; /* True global */
|
||||
#include <tchar.h>
|
||||
#define tsrm_strtok_r(a,b,c) _tcstok((a),(b))
|
||||
#define TOKENIZER_STRING "/\\"
|
||||
|
||||
static int php_check_dots(const char *element, int n)
|
||||
|
||||
static int php_check_dots(const char *element, int n)
|
||||
{
|
||||
while (n-- > 0) if (element[n] != '.') break;
|
||||
|
||||
return (n != -1);
|
||||
}
|
||||
|
||||
|
||||
#define IS_DIRECTORY_UP(element, len) \
|
||||
(len >= 2 && !php_check_dots(element, len))
|
||||
|
||||
@ -124,7 +137,7 @@ static int php_check_dots(const char *element, int n)
|
||||
|
||||
/* define this to check semantics */
|
||||
#define IS_DIR_OK(s) (1)
|
||||
|
||||
|
||||
#ifndef IS_DIR_OK
|
||||
#define IS_DIR_OK(state) (php_is_dir_ok(state) == 0)
|
||||
#endif
|
||||
@ -137,7 +150,7 @@ static int php_check_dots(const char *element, int n)
|
||||
|
||||
#define CWD_STATE_FREE(s) \
|
||||
free((s)->cwd);
|
||||
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
|
||||
#ifdef CTL_CODE
|
||||
@ -202,21 +215,86 @@ static inline time_t FileTimeToUnixTime(const FILETIME FileTime)
|
||||
return (time_t)UnixTime;
|
||||
}
|
||||
|
||||
CWD_API int php_sys_stat(const char *path, struct stat *buf) /* {{{ */
|
||||
CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len){ /* {{{ */
|
||||
HINSTANCE kernel32;
|
||||
HANDLE hFile;
|
||||
DWORD dwRet;
|
||||
|
||||
typedef BOOL (WINAPI *gfpnh_func)(HANDLE, LPTSTR, DWORD, DWORD);
|
||||
gfpnh_func pGetFinalPathNameByHandle;
|
||||
|
||||
kernel32 = LoadLibrary("kernel32.dll");
|
||||
|
||||
if (kernel32) {
|
||||
pGetFinalPathNameByHandle = (gfpnh_func)GetProcAddress(kernel32, "GetFinalPathNameByHandleA");
|
||||
if (pGetFinalPathNameByHandle == NULL) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
hFile = CreateFile(link, // file to open
|
||||
GENERIC_READ, // open for reading
|
||||
FILE_SHARE_READ, // share for reading
|
||||
NULL, // default security
|
||||
OPEN_EXISTING, // existing file only
|
||||
FILE_FLAG_BACKUP_SEMANTICS, // normal file
|
||||
NULL); // no attr. template
|
||||
|
||||
if( hFile == INVALID_HANDLE_VALUE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dwRet = pGetFinalPathNameByHandle(hFile, target, MAXPATHLEN, VOLUME_NAME_DOS);
|
||||
if(dwRet >= MAXPATHLEN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
|
||||
if(dwRet > 4) {
|
||||
/* Skip first 4 characters if they are "\??\" */
|
||||
if(target[0] == '\\' && target[1] == '\\' && target[2] == '?' && target[3] == '\\') {
|
||||
char tmp[MAXPATHLEN];
|
||||
unsigned int offset = 4;
|
||||
dwRet -= 4;
|
||||
|
||||
/* \??\UNC\ */
|
||||
if (dwRet > 7 && target[4] == 'U' && target[5] == 'N' && target[6] == 'C') {
|
||||
offset += 2;
|
||||
dwRet -= 2;
|
||||
target[offset] = '\\';
|
||||
}
|
||||
|
||||
memcpy(tmp, target + offset, dwRet);
|
||||
memcpy(target, tmp, dwRet);
|
||||
}
|
||||
}
|
||||
|
||||
target[dwRet] = '\0';
|
||||
return dwRet;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{{ */
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||
__int64 t;
|
||||
const size_t path_len = strlen(path);
|
||||
|
||||
if (!GetFileAttributesEx(path, GetFileExInfoStandard, &data)) {
|
||||
return stat(path, buf);
|
||||
}
|
||||
|
||||
if (path[1] == ':') {
|
||||
if (path_len >= 1 && path[1] == ':') {
|
||||
if (path[0] >= 'A' && path[0] <= 'Z') {
|
||||
buf->st_dev = buf->st_rdev = path[0] - 'A';
|
||||
} else {
|
||||
buf->st_dev = buf->st_rdev = path[0] - 'a';
|
||||
}
|
||||
} else if (IS_UNC_PATH(path, path_len)) {
|
||||
buf->st_dev = buf->st_rdev = 0;
|
||||
} else {
|
||||
char cur_path[MAXPATHLEN+1];
|
||||
DWORD len = sizeof(cur_path);
|
||||
@ -245,19 +323,56 @@ CWD_API int php_sys_stat(const char *path, struct stat *buf) /* {{{ */
|
||||
}
|
||||
if (tmp != cur_path) {
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buf->st_uid = buf->st_gid = buf->st_ino = 0;
|
||||
buf->st_mode = (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? (S_IFDIR|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)) : S_IFREG;
|
||||
buf->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6));
|
||||
|
||||
if (lstat && data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
/* File is a reparse point. Get the target */
|
||||
HANDLE hLink = NULL;
|
||||
REPARSE_DATA_BUFFER * pbuffer;
|
||||
unsigned int retlength = 0;
|
||||
TSRM_ALLOCA_FLAG(use_heap_large);
|
||||
|
||||
hLink = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if(hLink == INVALID_HANDLE_VALUE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pbuffer = (REPARSE_DATA_BUFFER *)tsrm_do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large);
|
||||
if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) {
|
||||
tsrm_free_alloca(pbuffer, use_heap_large);
|
||||
CloseHandle(hLink);
|
||||
return -1;
|
||||
}
|
||||
|
||||
CloseHandle(hLink);
|
||||
|
||||
if(pbuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
|
||||
buf->st_mode = S_IFLNK;
|
||||
buf->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6));
|
||||
}
|
||||
|
||||
#if 0 /* Not used yet */
|
||||
else if(pbuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
|
||||
buf->st_mode |=;
|
||||
}
|
||||
#endif
|
||||
tsrm_free_alloca(pbuffer, use_heap_large);
|
||||
} else {
|
||||
buf->st_mode = (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? (S_IFDIR|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)) : S_IFREG;
|
||||
buf->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6));
|
||||
}
|
||||
|
||||
if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||
int len = strlen(path);
|
||||
|
||||
if (path[len-4] == '.') {
|
||||
if (_memicmp(path+len-3, "exe", 3) == 0 ||
|
||||
_memicmp(path+len-3, "com", 3) == 0 ||
|
||||
_memicmp(path+len-3, "bat", 3) == 0 ||
|
||||
_memicmp(path+len-3, "cmd", 3) == 0) {
|
||||
_memicmp(path+len-3, "com", 3) == 0 ||
|
||||
_memicmp(path+len-3, "bat", 3) == 0 ||
|
||||
_memicmp(path+len-3, "cmd", 3) == 0) {
|
||||
buf->st_mode |= (S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6));
|
||||
}
|
||||
}
|
||||
@ -298,19 +413,19 @@ static int php_is_file_ok(const cwd_state *state) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC) /* {{{ */
|
||||
static void cwd_globals_ctor(virtual_cwd_globals *cwd_g TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state);
|
||||
cwd_globals->realpath_cache_size = 0;
|
||||
cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE;
|
||||
cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL;
|
||||
memset(cwd_globals->realpath_cache, 0, sizeof(cwd_globals->realpath_cache));
|
||||
CWD_STATE_COPY(&cwd_g->cwd, &main_cwd_state);
|
||||
cwd_g->realpath_cache_size = 0;
|
||||
cwd_g->realpath_cache_size_limit = REALPATH_CACHE_SIZE;
|
||||
cwd_g->realpath_cache_ttl = REALPATH_CACHE_TTL;
|
||||
memset(cwd_g->realpath_cache, 0, sizeof(cwd_g->realpath_cache));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals TSRMLS_DC) /* {{{ */
|
||||
static void cwd_globals_dtor(virtual_cwd_globals *cwd_g TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
CWD_STATE_FREE(&cwd_globals->cwd);
|
||||
CWD_STATE_FREE(&cwd_g->cwd);
|
||||
realpath_cache_clean(TSRMLS_C);
|
||||
}
|
||||
/* }}} */
|
||||
@ -332,7 +447,7 @@ CWD_API void virtual_cwd_startup(void) /* {{{ */
|
||||
}
|
||||
}
|
||||
#else
|
||||
result = getcwd(cwd, sizeof(cwd));
|
||||
result = getcwd(cwd, sizeof(cwd));
|
||||
#endif
|
||||
if (!result) {
|
||||
cwd[0] = '\0';
|
||||
@ -382,8 +497,11 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */
|
||||
|
||||
*length = 1;
|
||||
retval = (char *) malloc(2);
|
||||
if (retval == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
retval[0] = DEFAULT_SLASH;
|
||||
retval[1] = '\0';
|
||||
retval[1] = '\0';
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -394,6 +512,9 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */
|
||||
|
||||
*length = state->cwd_length+1;
|
||||
retval = (char *) malloc(*length+1);
|
||||
if (retval == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(retval, state->cwd, *length);
|
||||
retval[0] = toupper(retval[0]);
|
||||
retval[*length-1] = DEFAULT_SLASH;
|
||||
@ -493,7 +614,7 @@ CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC) /* {{{
|
||||
|
||||
while (*bucket != NULL) {
|
||||
if (key == (*bucket)->key && path_len == (*bucket)->path_len &&
|
||||
memcmp(path, (*bucket)->path, path_len) == 0) {
|
||||
memcmp(path, (*bucket)->path, path_len) == 0) {
|
||||
realpath_cache_bucket *r = *bucket;
|
||||
*bucket = (*bucket)->next;
|
||||
CWDG(realpath_cache_size) -= sizeof(realpath_cache_bucket) + r->path_len + 1 + r->realpath_len + 1;
|
||||
@ -510,9 +631,9 @@ static inline void realpath_cache_add(const char *path, int path_len, const char
|
||||
{
|
||||
long size = sizeof(realpath_cache_bucket) + path_len + 1;
|
||||
int same = 1;
|
||||
|
||||
|
||||
if (realpath_len != path_len ||
|
||||
memcmp(path, realpath, path_len) != 0) {
|
||||
memcmp(path, realpath, path_len) != 0) {
|
||||
size += realpath_len + 1;
|
||||
same = 0;
|
||||
}
|
||||
@ -521,6 +642,10 @@ static inline void realpath_cache_add(const char *path, int path_len, const char
|
||||
realpath_cache_bucket *bucket = malloc(size);
|
||||
unsigned long n;
|
||||
|
||||
if (bucket == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
bucket->key = realpath_cache_key(path, path_len TSRMLS_CC);
|
||||
#else
|
||||
@ -570,7 +695,7 @@ static inline realpath_cache_bucket* realpath_cache_find(const char *path, int p
|
||||
CWDG(realpath_cache_size) -= sizeof(realpath_cache_bucket) + r->path_len + 1 + r->realpath_len + 1;
|
||||
free(r);
|
||||
} else if (key == (*bucket)->key && path_len == (*bucket)->path_len &&
|
||||
memcmp(path, (*bucket)->path, path_len) == 0) {
|
||||
memcmp(path, (*bucket)->path, path_len) == 0) {
|
||||
return *bucket;
|
||||
} else {
|
||||
bucket = &(*bucket)->next;
|
||||
@ -582,21 +707,21 @@ static inline realpath_cache_bucket* realpath_cache_find(const char *path, int p
|
||||
|
||||
CWD_API realpath_cache_bucket* realpath_cache_lookup(const char *path, int path_len, time_t t TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return realpath_cache_find(path, path_len, t TSRMLS_CC);
|
||||
return realpath_cache_find(path, path_len, t TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
CWD_API int realpath_cache_size(TSRMLS_D)
|
||||
CWD_API int realpath_cache_size(TSRMLS_D)
|
||||
{
|
||||
return CWDG(realpath_cache_size);
|
||||
}
|
||||
|
||||
CWD_API int realpath_cache_max_buckets(TSRMLS_D)
|
||||
CWD_API int realpath_cache_max_buckets(TSRMLS_D)
|
||||
{
|
||||
return (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0]));
|
||||
}
|
||||
|
||||
CWD_API realpath_cache_bucket** realpath_cache_get_buckets(TSRMLS_D)
|
||||
CWD_API realpath_cache_bucket** realpath_cache_get_buckets(TSRMLS_D)
|
||||
{
|
||||
return CWDG(realpath_cache);
|
||||
}
|
||||
@ -650,14 +775,14 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
if (!start) {
|
||||
/* leading '..' must not be removed in case of relative path */
|
||||
if (j == 0 && path[0] == '.' && path[1] == '.' &&
|
||||
IS_SLASH(path[2])) {
|
||||
IS_SLASH(path[2])) {
|
||||
path[3] = '.';
|
||||
path[4] = '.';
|
||||
path[5] = DEFAULT_SLASH;
|
||||
j = 5;
|
||||
} else if (j > 0 &&
|
||||
path[j+1] == '.' && path[j+2] == '.' &&
|
||||
IS_SLASH(path[j+3])) {
|
||||
} else if (j > 0 &&
|
||||
path[j+1] == '.' && path[j+2] == '.' &&
|
||||
IS_SLASH(path[j+3])) {
|
||||
j += 4;
|
||||
path[j++] = '.';
|
||||
path[j++] = '.';
|
||||
@ -673,7 +798,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
path[len] = 0;
|
||||
|
||||
save = (use_realpath != CWD_EXPAND);
|
||||
@ -683,18 +808,18 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
if (!*t) {
|
||||
*t = time(0);
|
||||
}
|
||||
if ((bucket = realpath_cache_find(path, len, *t TSRMLS_CC)) != NULL) {
|
||||
if (is_dir && !bucket->is_dir) {
|
||||
if ((bucket = realpath_cache_find(path, len, *t TSRMLS_CC)) != NULL) {
|
||||
if (is_dir && !bucket->is_dir) {
|
||||
/* not a directory */
|
||||
return -1;
|
||||
} else {
|
||||
if (link_is_dir) {
|
||||
*link_is_dir = bucket->is_dir;
|
||||
}
|
||||
} else {
|
||||
if (link_is_dir) {
|
||||
*link_is_dir = bucket->is_dir;
|
||||
}
|
||||
memcpy(path, bucket->realpath, bucket->realpath_len + 1);
|
||||
return bucket->realpath_len;
|
||||
return bucket->realpath_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
@ -706,7 +831,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
/* continue resolution anyway but don't save result in the cache */
|
||||
save = 0;
|
||||
}
|
||||
|
||||
|
||||
if (save) {
|
||||
FindClose(hFind);
|
||||
}
|
||||
@ -714,9 +839,9 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
tmp = tsrm_do_alloca(len+1, use_heap);
|
||||
memcpy(tmp, path, len+1);
|
||||
|
||||
if(save &&
|
||||
!(IS_UNC_PATH(path, len) && len >= 3 && path[2] != '?') &&
|
||||
(data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
|
||||
if(save &&
|
||||
!(IS_UNC_PATH(path, len) && len >= 3 && path[2] != '?') &&
|
||||
(data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
|
||||
/* File is a reparse point. Get the target */
|
||||
HANDLE hLink = NULL;
|
||||
REPARSE_DATA_BUFFER * pbuffer;
|
||||
@ -739,6 +864,9 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
}
|
||||
|
||||
pbuffer = (REPARSE_DATA_BUFFER *)tsrm_do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large);
|
||||
if (pbuffer == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) {
|
||||
tsrm_free_alloca(pbuffer, use_heap_large);
|
||||
CloseHandle(hLink);
|
||||
@ -751,7 +879,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
reparsetarget = pbuffer->SymbolicLinkReparseBuffer.ReparseTarget;
|
||||
printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
|
||||
isabsolute = (pbuffer->SymbolicLinkReparseBuffer.Flags == 0) ? 1 : 0;
|
||||
if (!WideCharToMultiByte(CP_THREAD_ACP, 0,
|
||||
if (!WideCharToMultiByte(CP_THREAD_ACP, 0,
|
||||
reparsetarget + pbuffer->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR),
|
||||
printname_len + 1,
|
||||
printname, MAX_PATH, NULL, NULL
|
||||
@ -763,7 +891,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
printname[printname_len] = 0;
|
||||
|
||||
substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
|
||||
if (!WideCharToMultiByte(CP_THREAD_ACP, 0,
|
||||
if (!WideCharToMultiByte(CP_THREAD_ACP, 0,
|
||||
reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR),
|
||||
substitutename_len + 1,
|
||||
substitutename, MAX_PATH, NULL, NULL
|
||||
@ -777,7 +905,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
isabsolute = 1;
|
||||
reparsetarget = pbuffer->MountPointReparseBuffer.ReparseTarget;
|
||||
printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
|
||||
if (!WideCharToMultiByte(CP_THREAD_ACP, 0,
|
||||
if (!WideCharToMultiByte(CP_THREAD_ACP, 0,
|
||||
reparsetarget + pbuffer->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR),
|
||||
printname_len + 1,
|
||||
printname, MAX_PATH, NULL, NULL
|
||||
@ -788,7 +916,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
printname[pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR)] = 0;
|
||||
|
||||
substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
|
||||
if (!WideCharToMultiByte(CP_THREAD_ACP, 0,
|
||||
if (!WideCharToMultiByte(CP_THREAD_ACP, 0,
|
||||
reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR),
|
||||
substitutename_len + 1,
|
||||
substitutename, MAX_PATH, NULL, NULL
|
||||
@ -803,29 +931,31 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
}
|
||||
|
||||
if(isabsolute && substitutename_len > 4) {
|
||||
/* Do not resolve volumes (for now). A mounted point can
|
||||
/* Do not resolve volumes (for now). A mounted point can
|
||||
target a volume without a drive, it is not certain that
|
||||
all IO functions we use in php and its deps support
|
||||
all IO functions we use in php and its deps support
|
||||
path with volume GUID instead of the DOS way, like:
|
||||
d:\test\mnt\foo
|
||||
\\?\Volume{62d1c3f8-83b9-11de-b108-806e6f6e6963}\foo
|
||||
*/
|
||||
if (strncmp(substitutename, "\\??\\Volume{",11) == 0
|
||||
|| strncmp(substitutename, "\\\\?\\Volume{",11) == 0) {
|
||||
isVolume = TRUE;
|
||||
if (strncmp(substitutename, "\\??\\Volume{",11) == 0
|
||||
|| strncmp(substitutename, "\\\\?\\Volume{",11) == 0
|
||||
|| strncmp(substitutename, "\\??\\UNC\\", 8) == 0
|
||||
) {
|
||||
isVolume = TRUE;
|
||||
substitutename_off = 0;
|
||||
} else
|
||||
/* do not use the \??\ and \\?\ prefix*/
|
||||
if (strncmp(substitutename, "\\??\\", 4) == 0
|
||||
if (strncmp(substitutename, "\\??\\", 4) == 0
|
||||
|| strncmp(substitutename, "\\\\?\\", 4) == 0) {
|
||||
substitutename_off = 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isVolume) {
|
||||
char * tmp = substitutename + substitutename_off;
|
||||
char * tmp2 = substitutename + substitutename_off;
|
||||
for(bufindex = 0; bufindex < (substitutename_len - substitutename_off); bufindex++) {
|
||||
*(path + bufindex) = *(tmp + bufindex);
|
||||
*(path + bufindex) = *(tmp2 + bufindex);
|
||||
}
|
||||
|
||||
*(path + bufindex) = 0;
|
||||
@ -887,7 +1017,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
tmp = tsrm_do_alloca(len+1, use_heap);
|
||||
memcpy(tmp, path, len+1);
|
||||
#else
|
||||
if (save && lstat(path, &st) < 0) {
|
||||
if (save && php_sys_lstat(path, &st) < 0) {
|
||||
if (use_realpath == CWD_REALPATH) {
|
||||
/* file not found */
|
||||
return -1;
|
||||
@ -900,8 +1030,8 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
memcpy(tmp, path, len+1);
|
||||
|
||||
if (save && S_ISLNK(st.st_mode)) {
|
||||
if (++(*ll) > LINK_MAX || (j = readlink(tmp, path, MAXPATHLEN)) < 0) {
|
||||
/* too many links or broken symlinks */
|
||||
if (++(*ll) > LINK_MAX || (j = php_sys_readlink(tmp, path, MAXPATHLEN)) < 0) {
|
||||
/* too many links or broken symlinks */
|
||||
tsrm_free_alloca(tmp, use_heap);
|
||||
return -1;
|
||||
}
|
||||
@ -913,10 +1043,10 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (i + j >= MAXPATHLEN-1) {
|
||||
if (i + j >= MAXPATHLEN-1) {
|
||||
tsrm_free_alloca(tmp, use_heap);
|
||||
return -1; /* buffer overflow */
|
||||
}
|
||||
}
|
||||
memmove(path+i, path, j+1);
|
||||
memcpy(path, tmp, i-1);
|
||||
path[i-1] = DEFAULT_SLASH;
|
||||
@ -988,7 +1118,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
|
||||
/* Resolve path relatively to state and put the real path into state */
|
||||
/* returns 0 for ok, 1 for error */
|
||||
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath) /* {{{ */
|
||||
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
int path_length = strlen(path);
|
||||
char resolved_path[MAXPATHLEN];
|
||||
@ -998,7 +1128,6 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
|
||||
int ret;
|
||||
int add_slash;
|
||||
void *tmp;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (path_length == 0 || path_length >= MAXPATHLEN-1) {
|
||||
#ifdef TSRM_WIN32
|
||||
@ -1038,18 +1167,18 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
|
||||
state_cwd_length = 2;
|
||||
while (IS_SLASH(state->cwd[state_cwd_length])) {
|
||||
state_cwd_length++;
|
||||
}
|
||||
}
|
||||
while (state->cwd[state_cwd_length] &&
|
||||
!IS_SLASH(state->cwd[state_cwd_length])) {
|
||||
!IS_SLASH(state->cwd[state_cwd_length])) {
|
||||
state_cwd_length++;
|
||||
}
|
||||
}
|
||||
while (IS_SLASH(state->cwd[state_cwd_length])) {
|
||||
state_cwd_length++;
|
||||
}
|
||||
}
|
||||
while (state->cwd[state_cwd_length] &&
|
||||
!IS_SLASH(state->cwd[state_cwd_length])) {
|
||||
!IS_SLASH(state->cwd[state_cwd_length])) {
|
||||
state_cwd_length++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1061,7 +1190,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
|
||||
memcpy(resolved_path + state_cwd_length + 1, path, path_length + 1);
|
||||
path_length += state_cwd_length + 1;
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
#ifdef TSRM_WIN32
|
||||
if (path_length > 2 && path[1] == ':' && !IS_SLASH(path[2])) {
|
||||
resolved_path[0] = path[0];
|
||||
@ -1072,11 +1201,11 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
|
||||
} else
|
||||
#endif
|
||||
memcpy(resolved_path, path, path_length + 1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
if (memchr(resolved_path, '*', path_length) ||
|
||||
memchr(resolved_path, '?', path_length)) {
|
||||
memchr(resolved_path, '?', path_length)) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@ -1126,12 +1255,12 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
|
||||
add_slash = (use_realpath != CWD_REALPATH) && path_length > 0 && IS_SLASH(resolved_path[path_length-1]);
|
||||
t = CWDG(realpath_cache_ttl) ? 0 : -1;
|
||||
path_length = tsrm_realpath_r(resolved_path, start, path_length, &ll, &t, use_realpath, 0, NULL TSRMLS_CC);
|
||||
|
||||
|
||||
if (path_length < 0) {
|
||||
errno = ENOENT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (!start && !path_length) {
|
||||
resolved_path[path_length++] = '.';
|
||||
}
|
||||
@ -1184,7 +1313,7 @@ verify:
|
||||
memcpy(state->cwd, resolved_path, state->cwd_length+1);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
|
||||
#if VIRTUAL_CWD_DEBUG
|
||||
fprintf (stderr, "virtual_file_ex() = %s\n",state->cwd);
|
||||
#endif
|
||||
@ -1194,7 +1323,7 @@ verify:
|
||||
|
||||
CWD_API int virtual_chdir(const char *path TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return virtual_file_ex(&CWDG(cwd), path, php_is_dir_ok, CWD_REALPATH)?-1:0;
|
||||
return virtual_file_ex(&CWDG(cwd), path, php_is_dir_ok, CWD_REALPATH TSRMLS_CC)?-1:0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -1207,7 +1336,7 @@ CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path
|
||||
|
||||
if (length == 0) {
|
||||
return 1; /* Can't cd to empty string */
|
||||
}
|
||||
}
|
||||
while(--length >= 0 && !IS_SLASH(path[length])) {
|
||||
}
|
||||
|
||||
@ -1241,20 +1370,28 @@ CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC) /* {
|
||||
/* realpath("") returns CWD */
|
||||
if (!*path) {
|
||||
new_state.cwd = (char*)malloc(1);
|
||||
if (new_state.cwd == NULL) {
|
||||
retval = NULL;
|
||||
goto end;
|
||||
}
|
||||
new_state.cwd[0] = '\0';
|
||||
new_state.cwd_length = 0;
|
||||
if (VCWD_GETCWD(cwd, MAXPATHLEN)) {
|
||||
path = cwd;
|
||||
new_state.cwd_length = 0;
|
||||
if (VCWD_GETCWD(cwd, MAXPATHLEN)) {
|
||||
path = cwd;
|
||||
}
|
||||
} else if (!IS_ABSOLUTE_PATH(path, strlen(path))) {
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
} else {
|
||||
new_state.cwd = (char*)malloc(1);
|
||||
if (new_state.cwd == NULL) {
|
||||
retval = NULL;
|
||||
goto end;
|
||||
}
|
||||
new_state.cwd[0] = '\0';
|
||||
new_state.cwd_length = 0;
|
||||
new_state.cwd_length = 0;
|
||||
}
|
||||
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)==0) {
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)==0) {
|
||||
int len = new_state.cwd_length>MAXPATHLEN-1?MAXPATHLEN-1:new_state.cwd_length;
|
||||
|
||||
memcpy(real_path, new_state.cwd, len);
|
||||
@ -1265,7 +1402,7 @@ CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC) /* {
|
||||
}
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
|
||||
end:
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
@ -1276,7 +1413,7 @@ CWD_API int virtual_filepath_ex(const char *path, char **filepath, verify_path_f
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
retval = virtual_file_ex(&new_state, path, verify_path, CWD_FILEPATH);
|
||||
retval = virtual_file_ex(&new_state, path, verify_path, CWD_FILEPATH TSRMLS_CC);
|
||||
|
||||
*filepath = new_state.cwd;
|
||||
|
||||
@ -1301,7 +1438,7 @@ CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC) /* {{{
|
||||
}
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH)) {
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return NULL;
|
||||
}
|
||||
@ -1317,21 +1454,21 @@ CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
cwd_state new_state;
|
||||
int ret;
|
||||
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH)) {
|
||||
if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(TSRM_WIN32)
|
||||
ret = tsrm_win32_access(new_state.cwd, mode);
|
||||
ret = tsrm_win32_access(new_state.cwd, mode TSRMLS_CC);
|
||||
#else
|
||||
ret = access(new_state.cwd, mode);
|
||||
#endif
|
||||
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
@ -1352,12 +1489,12 @@ static void UnixTimeToFileTime(time_t t, LPFILETIME pft) /* {{{ */
|
||||
TSRM_API int win32_utime(const char *filename, struct utimbuf *buf) /* {{{ */
|
||||
{
|
||||
FILETIME mtime, atime;
|
||||
HANDLE hFile;
|
||||
HANDLE hFile;
|
||||
|
||||
hFile = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL,
|
||||
OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
|
||||
/* OPEN_ALWAYS mode sets the last error to ERROR_ALREADY_EXISTS but
|
||||
/* OPEN_ALWAYS mode sets the last error to ERROR_ALREADY_EXISTS but
|
||||
the CreateFile operation succeeds */
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
SetLastError(0);
|
||||
@ -1392,7 +1529,7 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC) /
|
||||
int ret;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH)) {
|
||||
if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
}
|
||||
@ -1415,7 +1552,7 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC) /* {{{ */
|
||||
int ret;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH)) {
|
||||
if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
}
|
||||
@ -1434,7 +1571,7 @@ CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int li
|
||||
int ret;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH)) {
|
||||
if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
}
|
||||
@ -1461,7 +1598,7 @@ CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...) /* {{{ */
|
||||
int f;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH)) {
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
}
|
||||
@ -1477,7 +1614,7 @@ CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...) /* {{{ */
|
||||
f = open(new_state.cwd, flags, mode);
|
||||
} else {
|
||||
f = open(new_state.cwd, flags);
|
||||
}
|
||||
}
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return f;
|
||||
}
|
||||
@ -1489,7 +1626,7 @@ CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC) /* {{{ */
|
||||
int f;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH)) {
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
}
|
||||
@ -1508,14 +1645,14 @@ CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC) /* {{{ */
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&old_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&old_state, oldname, NULL, CWD_EXPAND)) {
|
||||
if (virtual_file_ex(&old_state, oldname, NULL, CWD_EXPAND TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&old_state);
|
||||
return -1;
|
||||
}
|
||||
oldname = old_state.cwd;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, newname, NULL, CWD_EXPAND)) {
|
||||
if (virtual_file_ex(&new_state, newname, NULL, CWD_EXPAND TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&old_state);
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
@ -1544,7 +1681,7 @@ CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ */
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) {
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
}
|
||||
@ -1556,25 +1693,23 @@ CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#if !defined(TSRM_WIN32)
|
||||
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
cwd_state new_state;
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND)) {
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = lstat(new_state.cwd, buf);
|
||||
retval = php_sys_lstat(new_state.cwd, buf);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
CWD_API int virtual_unlink(const char *path TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
@ -1582,7 +1717,7 @@ CWD_API int virtual_unlink(const char *path TSRMLS_DC) /* {{{ */
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND)) {
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
}
|
||||
@ -1600,7 +1735,7 @@ CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC) /* {{{ */
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, pathname, NULL, CWD_FILEPATH)) {
|
||||
if (virtual_file_ex(&new_state, pathname, NULL, CWD_FILEPATH TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
}
|
||||
@ -1621,7 +1756,7 @@ CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC) /* {{{ */
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, pathname, NULL, CWD_EXPAND)) {
|
||||
if (virtual_file_ex(&new_state, pathname, NULL, CWD_EXPAND TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return -1;
|
||||
}
|
||||
@ -1643,7 +1778,7 @@ CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC) /* {{{ */
|
||||
DIR *retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH)) {
|
||||
if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH TSRMLS_CC)) {
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return NULL;
|
||||
}
|
||||
@ -1658,7 +1793,7 @@ CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC) /* {{{ */
|
||||
#ifdef TSRM_WIN32
|
||||
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return popen_ex(command, type, CWDG(cwd).cwd, NULL);
|
||||
return popen_ex(command, type, CWDG(cwd).cwd, NULL TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
#elif defined(NETWARE)
|
||||
@ -1738,7 +1873,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) /*
|
||||
}
|
||||
*ptr++ = '\'';
|
||||
}
|
||||
|
||||
|
||||
*ptr++ = ' ';
|
||||
*ptr++ = ';';
|
||||
*ptr++ = ' ';
|
||||
@ -1760,22 +1895,28 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{
|
||||
/* realpath("") returns CWD */
|
||||
if (!*path) {
|
||||
new_state.cwd = (char*)malloc(1);
|
||||
if (new_state.cwd == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new_state.cwd[0] = '\0';
|
||||
new_state.cwd_length = 0;
|
||||
if (VCWD_GETCWD(cwd, MAXPATHLEN)) {
|
||||
path = cwd;
|
||||
new_state.cwd_length = 0;
|
||||
if (VCWD_GETCWD(cwd, MAXPATHLEN)) {
|
||||
path = cwd;
|
||||
}
|
||||
} else if (!IS_ABSOLUTE_PATH(path, strlen(path)) &&
|
||||
VCWD_GETCWD(cwd, MAXPATHLEN)) {
|
||||
VCWD_GETCWD(cwd, MAXPATHLEN)) {
|
||||
new_state.cwd = strdup(cwd);
|
||||
new_state.cwd_length = strlen(cwd);
|
||||
} else {
|
||||
new_state.cwd = (char*)malloc(1);
|
||||
if (new_state.cwd == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new_state.cwd[0] = '\0';
|
||||
new_state.cwd_length = 0;
|
||||
new_state.cwd_length = 0;
|
||||
}
|
||||
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) {
|
||||
if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) {
|
||||
free(new_state.cwd);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
| Copyright (c) 1997-2011 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,6 +14,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Sascha Schumann <sascha@schumann.cx> |
|
||||
| Pierre Joye <pierre@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
@ -107,7 +108,7 @@ typedef unsigned short mode_t;
|
||||
#define COPY_WHEN_ABSOLUTE(path) 0
|
||||
#endif
|
||||
|
||||
#ifndef IS_ABSOLUTE_PATH
|
||||
#ifndef IS_ABSOLUTE_PATH
|
||||
#define IS_ABSOLUTE_PATH(path, len) \
|
||||
(IS_SLASH(path[0]))
|
||||
#endif
|
||||
@ -129,9 +130,16 @@ typedef unsigned short mode_t;
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
CWD_API int php_sys_stat(const char *path, struct stat *buf);
|
||||
CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat);
|
||||
# define php_sys_stat(path, buf) php_sys_stat_ex(path, buf, 0)
|
||||
# define php_sys_lstat(path, buf) php_sys_stat_ex(path, buf, 1)
|
||||
CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len);
|
||||
#else
|
||||
# define php_sys_stat stat
|
||||
# define php_sys_lstat lstat
|
||||
# ifdef HAVE_SYMLINK
|
||||
# define php_sys_readlink(link, target, target_len) readlink(link, target, target_len)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef struct _cwd_state {
|
||||
@ -155,9 +163,7 @@ CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...);
|
||||
CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC);
|
||||
CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC);
|
||||
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC);
|
||||
#if !defined(TSRM_WIN32)
|
||||
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC);
|
||||
#endif
|
||||
CWD_API int virtual_unlink(const char *path TSRMLS_DC);
|
||||
CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC);
|
||||
CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC);
|
||||
@ -188,14 +194,14 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC);
|
||||
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link TSRMLS_DC);
|
||||
#endif
|
||||
|
||||
/* One of the following constants must be used as the last argument
|
||||
/* One of the following constants must be used as the last argument
|
||||
in virtual_file_ex() call. */
|
||||
|
||||
#define CWD_EXPAND 0 /* expand "." and ".." but dont resolve symlinks */
|
||||
#define CWD_FILEPATH 1 /* resolve symlinks if file is exist otherwise expand */
|
||||
#define CWD_REALPATH 2 /* call realpath(), resolve symlinks. File must exist */
|
||||
|
||||
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath);
|
||||
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath TSRMLS_DC);
|
||||
|
||||
CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC);
|
||||
|
||||
@ -216,7 +222,7 @@ typedef struct _realpath_cache_bucket {
|
||||
unsigned char is_wvalid;
|
||||
unsigned char is_writable;
|
||||
#endif
|
||||
struct _realpath_cache_bucket *next;
|
||||
struct _realpath_cache_bucket *next;
|
||||
} realpath_cache_bucket;
|
||||
|
||||
typedef struct _virtual_cwd_globals {
|
||||
@ -244,7 +250,7 @@ CWD_API realpath_cache_bucket** realpath_cache_get_buckets(TSRMLS_D);
|
||||
|
||||
/* The actual macros to be used in programs using TSRM
|
||||
* If the program defines VIRTUAL_DIR it will use the
|
||||
* virtual_* functions
|
||||
* virtual_* functions
|
||||
*/
|
||||
|
||||
#ifdef VIRTUAL_DIR
|
||||
@ -261,9 +267,7 @@ CWD_API realpath_cache_bucket** realpath_cache_get_buckets(TSRMLS_D);
|
||||
#define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path TSRMLS_CC)
|
||||
#define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
|
||||
#define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
|
||||
#if !defined(TSRM_WIN32)
|
||||
# define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
|
||||
#endif
|
||||
#define VCWD_UNLINK(path) virtual_unlink(path TSRMLS_CC)
|
||||
#define VCWD_MKDIR(pathname, mode) virtual_mkdir(pathname, mode TSRMLS_CC)
|
||||
#define VCWD_RMDIR(pathname) virtual_rmdir(pathname TSRMLS_CC)
|
||||
@ -306,7 +310,7 @@ CWD_API realpath_cache_bucket** realpath_cache_get_buckets(TSRMLS_D);
|
||||
#define VCWD_OPENDIR(pathname) opendir(pathname)
|
||||
#define VCWD_POPEN(command, type) popen(command, type)
|
||||
#if defined(TSRM_WIN32)
|
||||
#define VCWD_ACCESS(pathname, mode) tsrm_win32_access(pathname, mode)
|
||||
#define VCWD_ACCESS(pathname, mode) tsrm_win32_access(pathname, mode TSRMLS_CC)
|
||||
#else
|
||||
#define VCWD_ACCESS(pathname, mode) access(pathname, mode)
|
||||
#endif
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
| Copyright (c) 1997-2011 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 |
|
||||
@ -190,7 +190,7 @@ Finished:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TSRM_API int tsrm_win32_access(const char *pathname, int mode)
|
||||
TSRM_API int tsrm_win32_access(const char *pathname, int mode TSRMLS_DC)
|
||||
{
|
||||
time_t t;
|
||||
HANDLE thread_token;
|
||||
@ -208,8 +208,6 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode)
|
||||
realpath_cache_bucket * bucket = NULL;
|
||||
char * real_path = NULL;
|
||||
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (mode == 1 /*X_OK*/) {
|
||||
DWORD type;
|
||||
return GetBinaryType(pathname, &type) ? 0 : -1;
|
||||
@ -448,10 +446,12 @@ static HANDLE dupHandle(HANDLE fh, BOOL inherit) {
|
||||
|
||||
TSRM_API FILE *popen(const char *command, const char *type)
|
||||
{
|
||||
return popen_ex(command, type, NULL, NULL);
|
||||
TSRMLS_FETCH();
|
||||
|
||||
return popen_ex(command, type, NULL, NULL TSRMLS_CC);
|
||||
}
|
||||
|
||||
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env)
|
||||
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env TSRMLS_DC)
|
||||
{
|
||||
FILE *stream = NULL;
|
||||
int fno, type_len = strlen(type), read, mode;
|
||||
@ -469,8 +469,6 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
|
||||
HANDLE token_user = NULL;
|
||||
BOOL asuser = TRUE;
|
||||
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (!type) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
| Copyright (c) 1997-2011 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 |
|
||||
@ -95,10 +95,10 @@ char * tsrm_win32_get_path_sid_key(const char *pathname TSRMLS_DC);
|
||||
TSRM_API void tsrm_win32_startup(void);
|
||||
TSRM_API void tsrm_win32_shutdown(void);
|
||||
|
||||
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env);
|
||||
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env TSRMLS_DC);
|
||||
TSRM_API FILE *popen(const char *command, const char *type);
|
||||
TSRM_API int pclose(FILE *stream);
|
||||
TSRM_API int tsrm_win32_access(const char *pathname, int mode);
|
||||
TSRM_API int tsrm_win32_access(const char *pathname, int mode TSRMLS_DC);
|
||||
TSRM_API int win32_utime(const char *filename, struct utimbuf *buf);
|
||||
|
||||
TSRM_API int shmget(int key, int size, int flags);
|
||||
|
203
UPGRADING.INTERNALS
Normal file
203
UPGRADING.INTERNALS
Normal file
@ -0,0 +1,203 @@
|
||||
$Id$
|
||||
|
||||
UPGRADE NOTES - PHP X.Y
|
||||
|
||||
1. Internal API changes
|
||||
a. virtual_file_ex
|
||||
b. stat/lstat support
|
||||
c. readlink support
|
||||
d. layout of some core ZE structures (zend_op_array, zend_class_entry, ...)
|
||||
e. Zend\zend_fast_cache.h has been removed
|
||||
f. streams that enclose private streams
|
||||
g. leak_variable
|
||||
h. API Signature changes
|
||||
|
||||
2. Build system changes
|
||||
a. Unix build system changes
|
||||
b. Windows build system changes
|
||||
|
||||
|
||||
========================
|
||||
1. Internal API changes
|
||||
========================
|
||||
|
||||
a. virtual_file_ex
|
||||
|
||||
virtual_file_ex takes now a TSRM context as last parameter:
|
||||
CWD_API int virtual_file_ex(cwd_state *state, const char *path,
|
||||
verify_path_func verify_path, int use_realpath TSRLS_DC);
|
||||
|
||||
|
||||
b. stat/lstat support
|
||||
|
||||
lstat is now available on all platforms. On unix-like platform
|
||||
php_sys_lstat is an alias to lstat (when avaible). On Windows it is now
|
||||
available using php_sys_lstat. php_sys_stat and php_sys_lstat usage is recommended
|
||||
instead of calling lstat directly, to ensure portability.
|
||||
|
||||
|
||||
c. readlink support
|
||||
|
||||
readlink is now available on all platforms. On unix-like platform
|
||||
php_sys_readlink is an alias to readlink (when avaible). On Windows it is now
|
||||
available using php_sys_readlink. php_sys_readlink usage is recommended
|
||||
instead of calling readlink directly, to ensure portability.
|
||||
|
||||
|
||||
d. layout of some core ZE structures (zend_op_array, zend_class_entry, ...)
|
||||
|
||||
. zend_function.pass_rest_by_reference is replaced by
|
||||
ZEND_ACC_PASS_REST_BY_REFERENCE in zend_function.fn_flags
|
||||
. zend_function.return_reference is replaced by ZEND_ACC_RETURN_REFERENCE
|
||||
in zend_function.fn_flags
|
||||
. zend_arg_info.required_num_args removed. it was needed only for internal
|
||||
functions. Now the first arg_info for internal function (which has special
|
||||
meaning) is represented by zend_internal_function_info structure.
|
||||
. zend_op_array.size, size_var, size_literal, current_brk_cont,
|
||||
backpatch_count moved into CG(context), because they are used only during
|
||||
compilation.
|
||||
. zend_op_array.start_op is moved into EG(start_op), because it's used
|
||||
only for 'interactive' execution of single top-level op-array.
|
||||
. zend_op_array.done_pass_two is replaced by ZEND_ACC_DONE_PASS_TWO in
|
||||
zend_op_array.fn_flags.
|
||||
. op_array.vars array is trimmed (reallocated) during pass_two.
|
||||
. zend_class_entry.constants_updated is replaced by
|
||||
ZEND_ACC_CONSTANTS_UPDATED in zend_class_entry.ce_flags
|
||||
. the size of zend_class_entry is reduced by sharing the same memory space
|
||||
by different information for internal and user classes.
|
||||
See zend_class_inttry.info union.
|
||||
|
||||
|
||||
e. Zend\zend_fast_cache.h
|
||||
|
||||
It should not have been used anymore since php5, but now this header has
|
||||
been removed. The following macros are not available anymore:
|
||||
|
||||
ZEND_FAST_ALLOC(p, type, fc_type)
|
||||
ZEND_FAST_FREE(p, fc_type)
|
||||
ZEND_FAST_ALLOC_REL(p, type, fc_type)
|
||||
ZEND_FAST_FREE_REL(p, fc_type)
|
||||
|
||||
Use emalloc, emalloc_rel, efree or efree_rel instead.
|
||||
|
||||
|
||||
f. Streams that enclose private streams
|
||||
|
||||
Some streams, like the temp:// stream, may enclose private streams. If the
|
||||
outer stream leaks due to a programming error or is not exposed through a
|
||||
zval (and therefore is not deleted when all the zvals are gone), it will
|
||||
be destroyed on shutdown.
|
||||
The problem is that the outer usually wants itself to close the inner stream,
|
||||
so that it may do any other shutdown action that requires the inner stream to
|
||||
be live (e.g. commit data to it). If the outer stream is exposed through a
|
||||
zval and the inner one isn't, this is not a problem because the outer stream
|
||||
will be freed when the zval is destroyed, which happens before the resources
|
||||
are destroyed on shutdown.
|
||||
On resource list shutdown, the cleanup happens in reverse order of resource
|
||||
creation, so if the inner stream was created in the opener of the outer stream,
|
||||
it will be destroyed first.
|
||||
The following functions were added to the streams API to force a predictable
|
||||
destruction order:
|
||||
|
||||
PHPAPI php_stream *php_stream_encloses(php_stream *enclosing, php_stream *enclosed);
|
||||
#define php_stream_free_enclosed(stream_enclosed, close_options)
|
||||
PHPAPI int _php_stream_free_enclosed(php_stream *stream_enclosed, int close_options TSRMLS_DC);
|
||||
|
||||
Additionally, the following member was added to php_stream:
|
||||
|
||||
struct _php_stream *enclosing_stream;
|
||||
|
||||
and the following macro was added:
|
||||
|
||||
#define PHP_STREAM_FREE_IGNORE_ENCLOSING 32
|
||||
|
||||
The function php_stream_encloses declares the first stream encloses the second.
|
||||
This has the effect that, when the inner stream is closed from a resource
|
||||
destructor it will abort and try to free its enclosing stream instead.
|
||||
To prevent this from happening when the inner stream is freed from the outer
|
||||
stream, the macro php_stream_free_enclosed should be used instead of
|
||||
php_stream_free/php_stream_close/php_stream_pclose, or the flag
|
||||
PHP_STREAM_FREE_IGNORE_ENCLOSING should be directly passed to php_stream_free.
|
||||
The outer stream cannot abstain, in its close callback, from closing the inner
|
||||
stream or clear the enclosing_stream pointer in its enclosed stream by calling
|
||||
php_stream_encloses with the 2nd argument NULL. If this is not done, there will
|
||||
be problems, so observe this requirement when using php_stream_encloses.
|
||||
|
||||
|
||||
g. leak_variable
|
||||
|
||||
The function leak_variable(variable [, leak_data]) was added. It is only
|
||||
available on debug builds. It increments the refcount of a zval or, if the
|
||||
second argument is true and the variable is either an object or a resource
|
||||
it increments the refcounts of those objects instead.
|
||||
|
||||
|
||||
h. API Signature changes
|
||||
|
||||
. zend_list_insert
|
||||
ZEND_API int zend_list_insert(void *ptr, int type TSRMLS_DC);
|
||||
call: zend_list_insert(a, SOMETYPE TSRMLS_CC);
|
||||
NB: If zend_list_insert is used to register a resource,
|
||||
ZEND_REGISTER_RESOURCE could be used instead.
|
||||
|
||||
. php_le_stream_context(TSRMLS_C)
|
||||
PHPAPI php_stream_context *php_stream_context_alloc(TSRMLS_D)
|
||||
call: context = php_stream_context_alloc(TSRMLS_C);
|
||||
|
||||
. php_stream_context_alloc
|
||||
PHPAPI php_stream_context *php_stream_context_alloc(TSRMLS_D);
|
||||
call: context = php_stream_context_alloc(TSRMLS_C);
|
||||
|
||||
. sapi_get_request_time(TSRMLS_D);
|
||||
SAPI_API double sapi_get_request_time(TSRMLS_D);
|
||||
|
||||
. sapi_register_default_post_reader
|
||||
SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D) TSRMLS_DC);
|
||||
|
||||
. sapi_register_treat_data
|
||||
SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC) TSRMLS_DC);
|
||||
|
||||
. sapi_register_input_filter
|
||||
SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC), unsigned int (*input_filter_init)(TSRMLS_D) TSRMLS_DC);
|
||||
|
||||
. tsrm_win32_access
|
||||
TSRM_API int tsrm_win32_access(const char *pathname, int mode TSRMLS_DC);
|
||||
|
||||
. popen_ex (win32)
|
||||
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env TSRMLS_DC);
|
||||
|
||||
. php_get_current_user
|
||||
PHPAPI php_get_current_user(TSRMLS_D)
|
||||
Call: char *user = php_get_current_user(TSRMLS_C);
|
||||
|
||||
. php_idate
|
||||
PHPAPI php_idate(char format, time_t ts, int localtime TSRMLS_DC)
|
||||
Call: int ret = php_idate(format, ts, localtime TSRMLS_CC)
|
||||
|
||||
. php_escape_html_entities
|
||||
(size_t parameters were ints, previous "quote_style" (now flags) has expanded meaning)
|
||||
PHPAPI char *php_escape_html_entities(unsigned char *old, size_t oldlen, size_t *newlen, int all, int flags, char *hint_charset TSRMLS_DC);
|
||||
|
||||
. php_escape_html_entities_ex
|
||||
PHPAPI char *php_escape_html_entities_ex(unsigned char *old, size_t oldlen, size_t *newlen, int all, int flags, char *hint_charset, zend_bool double_encode TSRMLS_DC);
|
||||
|
||||
. php_unescape_html_entities
|
||||
PHPAPI char *php_unescape_html_entities(unsigned char *old, size_t oldlen, size_t *newlen, int all, int flags, char *hint_charset TSRMLS_DC);
|
||||
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
========================
|
||||
|
||||
a. Unix build system changes
|
||||
|
||||
- Changes in SAPI module build:
|
||||
. When adding new binary SAPI (executable, like CLI/CGI/FPM) use CLI config.m4 and Makefile.frag files as templates and replace CLI/cli with your SAPI name.
|
||||
|
||||
- New macros:
|
||||
. PHP_INIT_DTRACE(providerdesc, header-file, sources [, module])
|
||||
|
||||
|
||||
b. Windows build system changes
|
||||
-
|
||||
|
@ -17,7 +17,7 @@ libZend_la_SOURCES=\
|
||||
zend_objects_API.c zend_ts_hash.c zend_stream.c \
|
||||
zend_default_classes.c \
|
||||
zend_iterators.c zend_interfaces.c zend_exceptions.c \
|
||||
zend_strtod.c zend_closures.c zend_float.c
|
||||
zend_strtod.c zend_closures.c zend_float.c zend_string.c
|
||||
|
||||
libZend_la_LDFLAGS =
|
||||
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
|
||||
|
@ -243,6 +243,10 @@ SOURCE=.\zend_stream.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_string.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -315,10 +319,6 @@ SOURCE=.\zend_extensions.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_fast_cache.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_globals.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -411,6 +411,10 @@ SOURCE=.\zend_stream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_string.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
21
Zend/Zend.m4
21
Zend/Zend.m4
@ -176,13 +176,6 @@ AC_ARG_ENABLE(inline-optimization,
|
||||
ZEND_INLINE_OPTIMIZATION=yes
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(zend-multibyte,
|
||||
[ --enable-zend-multibyte Compile with zend multibyte support], [
|
||||
ZEND_MULTIBYTE=$enableval
|
||||
],[
|
||||
ZEND_MULTIBYTE=no
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([virtual machine dispatch method])
|
||||
AC_MSG_RESULT($PHP_ZEND_VM)
|
||||
|
||||
@ -195,9 +188,6 @@ AC_MSG_RESULT($ZEND_INLINE_OPTIMIZATION)
|
||||
AC_MSG_CHECKING(whether to enable Zend debugging)
|
||||
AC_MSG_RESULT($ZEND_DEBUG)
|
||||
|
||||
AC_MSG_CHECKING(whether to enable Zend multibyte)
|
||||
AC_MSG_RESULT($ZEND_MULTIBYTE)
|
||||
|
||||
case $PHP_ZEND_VM in
|
||||
SWITCH)
|
||||
AC_DEFINE(ZEND_VM_KIND,ZEND_VM_KIND_SWITCH,[virtual machine dispatch method])
|
||||
@ -232,10 +222,6 @@ if test "$ZEND_MAINTAINER_ZTS" = "yes"; then
|
||||
LIBZEND_CPLUSPLUS_CHECKS
|
||||
fi
|
||||
|
||||
if test "$ZEND_MULTIBYTE" = "yes"; then
|
||||
AC_DEFINE(ZEND_MULTIBYTE, 1, [ ])
|
||||
fi
|
||||
|
||||
changequote({,})
|
||||
if test -n "$GCC" && test "$ZEND_INLINE_OPTIMIZATION" != "yes"; then
|
||||
INLINE_CFLAGS=`echo $ac_n "$CFLAGS $ac_c" | sed s/-O[0-9s]*//`
|
||||
@ -419,4 +405,11 @@ if test -r "/dev/urandom" && test -c "/dev/urandom"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(whether /dev/arandom exists)
|
||||
if test -r "/dev/arandom" && test -c "/dev/arandom"; then
|
||||
AC_DEFINE([HAVE_DEV_ARANDOM], 1, [Define if the target system has /dev/arandom device])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
fi
|
||||
|
@ -273,6 +273,10 @@ SOURCE=.\zend_stream.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_string.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -345,10 +349,6 @@ SOURCE=.\zend_extensions.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_fast_cache.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_globals.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -445,6 +445,10 @@ SOURCE=.\zend_stream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_string.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
| Copyright (c) 1998-2011 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
|
@ -4,7 +4,7 @@ dnl This file contains local autoconf functions.
|
||||
|
||||
AC_DEFUN([LIBZEND_BISON_CHECK],[
|
||||
# we only support certain bison versions
|
||||
bison_version_list="1.28 1.35 1.75 1.875 2.0 2.1 2.2 2.3 2.4 2.4.1"
|
||||
bison_version_list="1.28 1.35 1.75 1.875 2.0 2.1 2.2 2.3 2.4 2.4.1 2.4.2 2.4.3"
|
||||
|
||||
# for standalone build of Zend Engine
|
||||
test -z "$SED" && SED=sed
|
||||
|
@ -3,7 +3,6 @@ if (function_exists("date_default_timezone_set")) {
|
||||
date_default_timezone_set("UTC");
|
||||
}
|
||||
|
||||
date_default_timezone_set('UTC');
|
||||
function simple() {
|
||||
$a = 0;
|
||||
for ($i = 0; $i < 1000000; $i++)
|
||||
|
321
Zend/micro_bench.php
Normal file
321
Zend/micro_bench.php
Normal file
@ -0,0 +1,321 @@
|
||||
<?php
|
||||
|
||||
function hallo() {
|
||||
}
|
||||
|
||||
function simpleucall($n) {
|
||||
for ($i = 0; $i < $n; $i++)
|
||||
hallo();
|
||||
}
|
||||
|
||||
function simpleudcall($n) {
|
||||
for ($i = 0; $i < $n; $i++)
|
||||
hallo2();
|
||||
}
|
||||
|
||||
function hallo2() {
|
||||
}
|
||||
|
||||
function simpleicall($n) {
|
||||
for ($i = 0; $i < $n; $i++)
|
||||
func_num_args();
|
||||
}
|
||||
|
||||
class Foo {
|
||||
static $a = 0;
|
||||
public $b = 0;
|
||||
const TEST = 0;
|
||||
|
||||
static function read_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = self::$a;
|
||||
}
|
||||
}
|
||||
|
||||
static function write_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
self::$a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static function isset_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = isset(self::$a);
|
||||
}
|
||||
}
|
||||
|
||||
static function empty_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = empty(self::$a);
|
||||
}
|
||||
}
|
||||
|
||||
static function f() {
|
||||
}
|
||||
|
||||
static function call_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
self::f();
|
||||
}
|
||||
}
|
||||
|
||||
function read_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $this->b;
|
||||
}
|
||||
}
|
||||
|
||||
function write_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$this->b = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function assign_add_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$this->b += 2;
|
||||
}
|
||||
}
|
||||
|
||||
function pre_inc_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
++$this->b;
|
||||
}
|
||||
}
|
||||
|
||||
function pre_dec_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
--$this->b;
|
||||
}
|
||||
}
|
||||
|
||||
function post_inc_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$this->b++;
|
||||
}
|
||||
}
|
||||
|
||||
function post_dec_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$this->b--;
|
||||
}
|
||||
}
|
||||
|
||||
function isset_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = isset($this->b);
|
||||
}
|
||||
}
|
||||
|
||||
function empty_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = empty($this->b);
|
||||
}
|
||||
}
|
||||
|
||||
function g() {
|
||||
}
|
||||
|
||||
function call($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$this->g();
|
||||
}
|
||||
}
|
||||
|
||||
function read_const($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $this::TEST;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function read_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = Foo::$a;
|
||||
}
|
||||
}
|
||||
|
||||
function write_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
Foo::$a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function isset_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = isset(Foo::$a);
|
||||
}
|
||||
}
|
||||
|
||||
function empty_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = empty(Foo::$a);
|
||||
}
|
||||
}
|
||||
|
||||
function call_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
Foo::f();
|
||||
}
|
||||
}
|
||||
|
||||
function create_object($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = new Foo();
|
||||
}
|
||||
}
|
||||
|
||||
define('TEST', null);
|
||||
|
||||
function read_const($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = TEST;
|
||||
}
|
||||
}
|
||||
|
||||
function read_auto_global($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $_GET;
|
||||
}
|
||||
}
|
||||
|
||||
$g_var = 0;
|
||||
|
||||
function read_global_var($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $GLOBALS['g_var'];
|
||||
}
|
||||
}
|
||||
|
||||
function read_hash($n) {
|
||||
$hash = array('test' => 0);
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $hash['test'];
|
||||
}
|
||||
}
|
||||
|
||||
function read_str_offset($n) {
|
||||
$str = "test";
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $str[1];
|
||||
}
|
||||
}
|
||||
|
||||
/*****/
|
||||
|
||||
function empty_loop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
}
|
||||
}
|
||||
|
||||
function getmicrotime()
|
||||
{
|
||||
$t = gettimeofday();
|
||||
return ($t['sec'] + $t['usec'] / 1000000);
|
||||
}
|
||||
|
||||
function start_test()
|
||||
{
|
||||
ob_start();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function end_test($start, $name, $overhead = null)
|
||||
{
|
||||
global $total;
|
||||
global $last_time;
|
||||
$end = getmicrotime();
|
||||
ob_end_clean();
|
||||
$last_time = $end-$start;
|
||||
$total += $last_time;
|
||||
$num = number_format($last_time,3);
|
||||
$pad = str_repeat(" ", 24-strlen($name)-strlen($num));
|
||||
if (is_null($overhead)) {
|
||||
echo $name.$pad.$num."\n";
|
||||
} else {
|
||||
$num2 = number_format($last_time - $overhead,3);
|
||||
echo $name.$pad.$num." ".$num2."\n";
|
||||
}
|
||||
ob_start();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function total()
|
||||
{
|
||||
global $total;
|
||||
$pad = str_repeat("-", 24);
|
||||
echo $pad."\n";
|
||||
$num = number_format($total,3);
|
||||
$pad = str_repeat(" ", 24-strlen("Total")-strlen($num));
|
||||
echo "Total".$pad.$num."\n";
|
||||
}
|
||||
|
||||
const N = 5000000;
|
||||
|
||||
$t0 = $t = start_test();
|
||||
empty_loop(N);
|
||||
$t = end_test($t, 'empty_loop');
|
||||
$overhead = $last_time;
|
||||
simpleucall(N);
|
||||
$t = end_test($t, 'func()', $overhead);
|
||||
simpleudcall(N);
|
||||
$t = end_test($t, 'undef_func()', $overhead);
|
||||
simpleicall(N);
|
||||
$t = end_test($t, 'int_func()', $overhead);
|
||||
Foo::read_static(N);
|
||||
$t = end_test($t, '$x = self::$x', $overhead);
|
||||
Foo::write_static(N);
|
||||
$t = end_test($t, 'self::$x = 0', $overhead);
|
||||
Foo::isset_static(N);
|
||||
$t = end_test($t, 'isset(self::$x)', $overhead);
|
||||
Foo::empty_static(N);
|
||||
$t = end_test($t, 'empty(self::$x)', $overhead);
|
||||
read_static(N);
|
||||
$t = end_test($t, '$x = Foo::$x', $overhead);
|
||||
write_static(N);
|
||||
$t = end_test($t, 'Foo::$x = 0', $overhead);
|
||||
isset_static(N);
|
||||
$t = end_test($t, 'isset(Foo::$x)', $overhead);
|
||||
empty_static(N);
|
||||
$t = end_test($t, 'empty(Foo::$x)', $overhead);
|
||||
Foo::call_static(N);
|
||||
$t = end_test($t, 'self::f()', $overhead);
|
||||
call_static(N);
|
||||
$t = end_test($t, 'Foo::f()', $overhead);
|
||||
$x = new Foo();
|
||||
$x->read_prop(N);
|
||||
$t = end_test($t, '$x = $this->x', $overhead);
|
||||
$x->write_prop(N);
|
||||
$t = end_test($t, '$this->x = 0', $overhead);
|
||||
$x->assign_add_prop(N);
|
||||
$t = end_test($t, '$this->x += 2', $overhead);
|
||||
$x->pre_inc_prop(N);
|
||||
$t = end_test($t, '++$this->x', $overhead);
|
||||
$x->pre_dec_prop(N);
|
||||
$t = end_test($t, '--$this->x', $overhead);
|
||||
$x->post_inc_prop(N);
|
||||
$t = end_test($t, '$this->x++', $overhead);
|
||||
$x->post_dec_prop(N);
|
||||
$t = end_test($t, '$this->x--', $overhead);
|
||||
$x->isset_prop(N);
|
||||
$t = end_test($t, 'isset($this->x)', $overhead);
|
||||
$x->empty_prop(N);
|
||||
$t = end_test($t, 'empty($this->x)', $overhead);
|
||||
$x->call(N);
|
||||
$t = end_test($t, '$this->f()', $overhead);
|
||||
$x->read_const(N);
|
||||
$t = end_test($t, '$x = Foo::TEST', $overhead);
|
||||
create_object(N);
|
||||
$t = end_test($t, 'new Foo()', $overhead);
|
||||
read_const(N);
|
||||
$t = end_test($t, '$x = TEST', $overhead);
|
||||
read_auto_global(N);
|
||||
$t = end_test($t, '$x = $_GET', $overhead);
|
||||
read_global_var(N);
|
||||
$t = end_test($t, '$x = $GLOBALS[\'v\']', $overhead);
|
||||
read_hash(N);
|
||||
$t = end_test($t, '$x = $hash[\'v\']', $overhead);
|
||||
read_str_offset(N);
|
||||
$t = end_test($t, '$x = $str[0]', $overhead);
|
||||
total($t0, "Total");
|
@ -21,5 +21,5 @@ print "ok\n";
|
||||
Notice: Trying to get property of non-object in %s on line %d
|
||||
ok
|
||||
|
||||
Strict Standards: Creating default object from empty value in %s on line %d
|
||||
Warning: Creating default object from empty value in %s on line %d
|
||||
ok
|
||||
|
@ -26,6 +26,6 @@ Notice: Undefined variable: arr in %s on line %d
|
||||
|
||||
Notice: Trying to get property of non-object in %s on line %d
|
||||
|
||||
Strict Standards: Creating default object from empty value in %s on line %d
|
||||
Warning: Creating default object from empty value in %s on line %d
|
||||
|
||||
Strict Standards: Creating default object from empty value in %s on line %d
|
||||
Warning: Creating default object from empty value in %s on line %d
|
||||
|
@ -12,4 +12,4 @@ foo(123);
|
||||
--EXPECTF--
|
||||
3
|
||||
|
||||
Catchable fatal error: Argument 1 passed to foo() must be an array, integer given, called in %sarray_type_hint_001.php on line 7 and defined in %sarray_type_hint_001.php on line 2
|
||||
Catchable fatal error: Argument 1 passed to foo() must be of the type array, integer given, called in %sarray_type_hint_001.php on line 7 and defined in %sarray_type_hint_001.php on line 2
|
||||
|
@ -23,7 +23,6 @@ echo isset($simpleString[0])?"ok\n":"bug\n";
|
||||
echo isset($simpleString["0"])?"ok\n":"bug\n";
|
||||
echo isset($simpleString["16"])?"ok\n":"bug\n";
|
||||
echo isset($simpleString["17"])?"bug\n":"ok\n";
|
||||
echo isset($simpleString["wrong"][0])?"bug\n":"ok\n";
|
||||
echo $simpleString->wrong === null?"ok\n":"bug\n";
|
||||
echo $simpleString["wrong"] === "B"?"ok\n":"bug\n";
|
||||
echo $simpleString["0"] === "B"?"ok\n":"bug\n";
|
||||
@ -44,7 +43,6 @@ ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
|
||||
Notice: Trying to get property of non-object in %sbug31098.php on line %d
|
||||
ok
|
||||
|
@ -17,22 +17,8 @@ array(1) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
&array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
*RECURSION*
|
||||
}
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
&array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
*RECURSION*
|
||||
}
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
|
@ -20,46 +20,17 @@ array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
&array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
*RECURSION*
|
||||
}
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
&array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
*RECURSION*
|
||||
}
|
||||
*RECURSION*
|
||||
}
|
||||
[2]=>
|
||||
&array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
&array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
*RECURSION*
|
||||
}
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
&array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
*RECURSION*
|
||||
}
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,29 +11,15 @@ var_dump($a);
|
||||
$a->b = null;
|
||||
$a = null;
|
||||
?>
|
||||
--EXPECT--
|
||||
object(stdClass)#1 (1) {
|
||||
--EXPECTF--
|
||||
object(stdClass)#%d (1) {
|
||||
["b"]=>
|
||||
&array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
&array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
*RECURSION*
|
||||
}
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
&array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
*RECURSION*
|
||||
[2]=>
|
||||
*RECURSION*
|
||||
}
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
|
@ -12,30 +12,16 @@ var_dump($a);
|
||||
$a->x0->y1 = "ok\n";
|
||||
echo $a->x0;
|
||||
?>
|
||||
--EXPECT--
|
||||
object(stdClass)#1 (1) {
|
||||
--EXPECTF--
|
||||
object(stdClass)#%d (1) {
|
||||
["x0"]=>
|
||||
&object(stdClass)#2 (3) {
|
||||
&object(stdClass)#%d (3) {
|
||||
["y0"]=>
|
||||
string(1) "b"
|
||||
["y1"]=>
|
||||
&object(stdClass)#2 (3) {
|
||||
["y0"]=>
|
||||
string(1) "b"
|
||||
["y1"]=>
|
||||
*RECURSION*
|
||||
["y2"]=>
|
||||
*RECURSION*
|
||||
}
|
||||
*RECURSION*
|
||||
["y2"]=>
|
||||
&object(stdClass)#2 (3) {
|
||||
["y0"]=>
|
||||
string(1) "b"
|
||||
["y1"]=>
|
||||
*RECURSION*
|
||||
["y2"]=>
|
||||
*RECURSION*
|
||||
}
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
ok
|
||||
|
@ -30,7 +30,9 @@ if (defined("pass3")) {
|
||||
set_error_handler('errorHandler');
|
||||
define("pass2", 1);
|
||||
include(__FILE__);
|
||||
print "ok\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Error: Redefining already defined constructor for class TestClass (%sbug35634.php:12)
|
||||
--EXPECT--
|
||||
ok
|
||||
|
@ -4,7 +4,6 @@ Bug #35655 (whitespace following end of heredoc is lost)
|
||||
highlight.string = #DD0000
|
||||
highlight.comment = #FF8000
|
||||
highlight.keyword = #007700
|
||||
highlight.bg = #FFFFFF
|
||||
highlight.default = #0000BB
|
||||
highlight.html = #000000
|
||||
--FILE--
|
||||
|
@ -63,10 +63,18 @@ print "\nDone\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
|
||||
Notice: Uninitialized string offset: %i in %s on line 6
|
||||
|
||||
Notice: Uninitialized string offset: 0 in %s on line 10
|
||||
|
||||
Notice: Uninitialized string offset: 0 in %s on line 12
|
||||
|
||||
Notice: Uninitialized string offset: %i in %s on line 14
|
||||
|
||||
Notice: Uninitialized string offset: %i in %s on line 16
|
||||
|
||||
Notice: Uninitialized string offset: 0 in %s on line 18
|
||||
|
||||
Notice: Uninitialized string offset: 4 in %s on line 28
|
||||
|
||||
Notice: Uninitialized string offset: 4 in %s on line 34
|
||||
@ -77,6 +85,8 @@ Notice: Uninitialized string offset: 4 in %s on line 42
|
||||
|
||||
Notice: Uninitialized string offset: 4 in %s on line 46
|
||||
|
||||
Notice: Uninitialized string offset: 12 in %s on line 50
|
||||
|
||||
Notice: Uninitialized string offset: 12 in %s on line 52
|
||||
b
|
||||
Done
|
||||
|
@ -1,5 +1,7 @@
|
||||
--TEST--
|
||||
Bug #39304 (Segmentation fault with list unpacking of string offset)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.4.0', '>=')) die('skip ZendEngine 2.4 needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$s = "";
|
||||
|
18
Zend/tests/bug39304_2_4.phpt
Normal file
18
Zend/tests/bug39304_2_4.phpt
Normal file
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Bug #39304 (Segmentation fault with list unpacking of string offset)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.4.0', '<')) die('skip ZendEngine 2.4 needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$s = "";
|
||||
list($a, $b) = $s[0];
|
||||
var_dump($a,$b);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Uninitialized string offset: 0 in %sbug39304_2_4.php on line 3
|
||||
|
||||
Notice: Uninitialized string offset: 1 in %sbug39304_2_4.php on line 3
|
||||
|
||||
Notice: Uninitialized string offset: 0 in %sbug39304_2_4.php on line 3
|
||||
string(0) ""
|
||||
string(0) ""
|
@ -4,7 +4,6 @@ Bug #42767 (highlight_string() truncates trailing comments)
|
||||
highlight.string = #DD0000
|
||||
highlight.comment = #FF8000
|
||||
highlight.keyword = #007700
|
||||
highlight.bg = #FFFFFF
|
||||
highlight.default = #0000BB
|
||||
highlight.html = #000000
|
||||
--FILE--
|
||||
|
@ -43,11 +43,11 @@ __call:
|
||||
string(3) "ABC"
|
||||
__call:
|
||||
string(3) "ABC"
|
||||
__callstatic:
|
||||
__call:
|
||||
string(3) "XYZ"
|
||||
__callstatic:
|
||||
__call:
|
||||
string(3) "WWW"
|
||||
__callstatic:
|
||||
__call:
|
||||
string(3) "ABC"
|
||||
__callstatic:
|
||||
string(1) "A"
|
||||
@ -58,4 +58,4 @@ string(1) "C"
|
||||
__callstatic:
|
||||
string(3) "FOO"
|
||||
__callstatic:
|
||||
string(3) "FOO"
|
||||
string(3) "FOO"
|
@ -35,17 +35,17 @@ call_user_func('self::y');
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
__callstatic:
|
||||
__call:
|
||||
string(3) "ABC"
|
||||
__callstatic:
|
||||
__call:
|
||||
string(3) "ABC"
|
||||
__call:
|
||||
string(3) "xyz"
|
||||
__callstatic:
|
||||
__call:
|
||||
string(3) "www"
|
||||
__call:
|
||||
string(1) "y"
|
||||
__callstatic:
|
||||
__call:
|
||||
string(1) "y"
|
||||
ok
|
||||
__callstatic:
|
||||
|
@ -29,8 +29,6 @@ $b->A();
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
|
||||
Strict Standards: Redefining already defined constructor for class A in %s on line %d
|
||||
B::__construct
|
||||
A::__construct
|
||||
B::A
|
||||
|
@ -16,7 +16,4 @@ $c = new c();
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
|
||||
Strict Standards: Redefining already defined constructor for class a in %s on line %d
|
||||
|
||||
Fatal error: Call to undefined method b::b() in %s on line %d
|
||||
|
16
Zend/tests/bug48930.phpt
Normal file
16
Zend/tests/bug48930.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Bug #48930 (__COMPILER_HALT_OFFSET__ incorrect in PHP>=5.3)
|
||||
--FILE--
|
||||
#!php
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Test
|
||||
*/
|
||||
printf("__COMPILER_HALT_OFFSET__ is %d\n",__COMPILER_HALT_OFFSET__);
|
||||
|
||||
__halt_compiler();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
__COMPILER_HALT_OFFSET__ is 116
|
28
Zend/tests/bug49893.phpt
Normal file
28
Zend/tests/bug49893.phpt
Normal file
@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
Bug #49893 (Crash while creating an instance of Zend_Mail_Storage_Pop3)
|
||||
--FILE--
|
||||
<?php
|
||||
class A {
|
||||
function __destruct() {
|
||||
try {
|
||||
throw new Exception("2");
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
class B {
|
||||
function __construct() {
|
||||
$this->a = new A();
|
||||
throw new Exception("1");
|
||||
}
|
||||
}
|
||||
try {
|
||||
$b = new B();
|
||||
} catch(Exception $e) {
|
||||
echo $e->getMessage() . "\n";;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
2
|
||||
1
|
@ -27,6 +27,6 @@ $foo->start();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
static
|
||||
static
|
||||
static
|
||||
instance
|
||||
instance
|
||||
instance
|
16
Zend/tests/bug51394.phpt
Normal file
16
Zend/tests/bug51394.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Bug #51394 (Error line reported incorrectly if error handler throws an exception)
|
||||
--INI--
|
||||
error_reporting=-1
|
||||
--FILE--
|
||||
<?php
|
||||
function eh()
|
||||
{
|
||||
throw new Exception("error!");
|
||||
return false;
|
||||
}
|
||||
|
||||
set_error_handler("eh");
|
||||
$a = $empty($b);
|
||||
--EXPECTF--
|
||||
Fatal error: Function name must be a string in %sbug51394.php on line 9
|
18
Zend/tests/bug51421.phpt
Normal file
18
Zend/tests/bug51421.phpt
Normal file
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Bug #51421 (Abstract __construct constructor argument list not enforced)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class ExampleClass {}
|
||||
|
||||
abstract class TestInterface {
|
||||
abstract public function __construct(ExampleClass $var);
|
||||
}
|
||||
|
||||
class Test extends TestInterface {
|
||||
public function __construct() {}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Declaration of Test::__construct() must be compatible with that of TestInterface::__construct() in %s on line %d
|
14
Zend/tests/bug51791.phpt
Normal file
14
Zend/tests/bug51791.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Bug #51791 (constant() failed to check undefined constant and php interpreter stoped)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
const B = 1;
|
||||
}
|
||||
var_dump(constant('A::B1'));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: constant(): Couldn't find constant A::B1 in %s on line %d
|
||||
NULL
|
40
Zend/tests/bug51822.phpt
Normal file
40
Zend/tests/bug51822.phpt
Normal file
@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
Bug #51822 (Segfault with strange __destruct() for static class variables)
|
||||
--FILE--
|
||||
<?php
|
||||
class DestructableObject
|
||||
{
|
||||
public function __destruct()
|
||||
{
|
||||
echo "2\n";
|
||||
}
|
||||
}
|
||||
|
||||
class DestructorCreator
|
||||
{
|
||||
public function __destruct()
|
||||
{
|
||||
$this->test = new DestructableObject;
|
||||
echo "1\n";
|
||||
}
|
||||
}
|
||||
|
||||
class Test
|
||||
{
|
||||
public static $mystatic;
|
||||
}
|
||||
|
||||
// Uncomment this to avoid segfault
|
||||
//Test::$mystatic = new DestructorCreator();
|
||||
|
||||
$x = new Test();
|
||||
|
||||
if (!isset(Test::$mystatic))
|
||||
Test::$mystatic = new DestructorCreator();
|
||||
|
||||
echo "bla\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
bla
|
||||
1
|
||||
2
|
19
Zend/tests/bug51827.phpt
Normal file
19
Zend/tests/bug51827.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Bug #51827 (Bad warning when register_shutdown_function called with wrong num of parameters)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
function abc() {
|
||||
var_dump(1);
|
||||
}
|
||||
|
||||
register_shutdown_function('timE');
|
||||
register_shutdown_function('ABC');
|
||||
register_shutdown_function('exploDe');
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
int(1)
|
||||
|
||||
Warning: explode() expects at least 2 parameters, 0 given in Unknown on line %d
|
17
Zend/tests/bug52001.phpt
Normal file
17
Zend/tests/bug52001.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Bug #52001 (Memory allocation problems after using variable variables)
|
||||
--FILE--
|
||||
<?php
|
||||
a(0,$$var);
|
||||
|
||||
$temp1=1;
|
||||
$temp2=2;
|
||||
var_dump($temp1);
|
||||
|
||||
function a($b,$c) {}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Undefined variable: var in %sbug52001.php on line 2
|
||||
|
||||
Notice: Undefined variable: in %sbug52001.php on line 2
|
||||
int(1)
|
75
Zend/tests/bug52041.phpt
Normal file
75
Zend/tests/bug52041.phpt
Normal file
@ -0,0 +1,75 @@
|
||||
--TEST--
|
||||
Bug #52041 (Memory leak when writing on uninitialized variable returned from function)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo() {
|
||||
return $x;
|
||||
}
|
||||
|
||||
foo()->a = 1;
|
||||
foo()->a->b = 2;
|
||||
foo()->a++;
|
||||
foo()->a->b++;
|
||||
foo()->a += 2;
|
||||
foo()->a->b += 2;
|
||||
|
||||
foo()[0] = 1;
|
||||
foo()[0][0] = 2;
|
||||
foo()[0]++;
|
||||
foo()[0][0]++;
|
||||
foo()[0] += 2;
|
||||
foo()[0][0] += 2;
|
||||
|
||||
var_dump(foo());
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
|
||||
Warning: Creating default object from empty value in %sbug52041.php on line 6
|
||||
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
|
||||
Warning: Creating default object from empty value in %sbug52041.php on line 7
|
||||
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
|
||||
Warning: Creating default object from empty value in %sbug52041.php on line 8
|
||||
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
|
||||
Warning: Creating default object from empty value in %sbug52041.php on line 9
|
||||
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
|
||||
Warning: Creating default object from empty value in %sbug52041.php on line 10
|
||||
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
|
||||
Warning: Creating default object from empty value in %sbug52041.php on line 11
|
||||
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
|
||||
Notice: Undefined variable: x in %stests/bug52041.php on line 3
|
||||
|
||||
Notice: Undefined offset: 0 in %sbug52041.php on line 15
|
||||
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
|
||||
Notice: Undefined offset: 0 in %sbug52041.php on line 16
|
||||
|
||||
Notice: Undefined offset: 0 in %sbug52041.php on line 16
|
||||
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
|
||||
Notice: Undefined offset: 0 in %sbug52041.php on line 17
|
||||
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
|
||||
Notice: Undefined offset: 0 in %sbug52041.php on line 18
|
||||
|
||||
Notice: Undefined offset: 0 in %sbug52041.php on line 18
|
||||
|
||||
Notice: Undefined variable: x in %sbug52041.php on line 3
|
||||
NULL
|
27
Zend/tests/bug52051.phpt
Normal file
27
Zend/tests/bug52051.phpt
Normal file
@ -0,0 +1,27 @@
|
||||
--TEST--
|
||||
Bug #52051 (handling of case sensitivity of old-style constructors changed in 5.3+)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class AA {
|
||||
function AA() { echo "foo\n"; }
|
||||
}
|
||||
class bb extends AA {}
|
||||
class CC extends bb {
|
||||
function CC() { parent::bb(); }
|
||||
}
|
||||
new CC();
|
||||
|
||||
class A {
|
||||
function A() { echo "bar\n"; }
|
||||
}
|
||||
class B extends A {}
|
||||
class C extends B {
|
||||
function C() { parent::B(); }
|
||||
}
|
||||
new C();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
foo
|
||||
bar
|
12
Zend/tests/bug52060.phpt
Normal file
12
Zend/tests/bug52060.phpt
Normal file
@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Bug #52060 (Memory leak when passing a closure to method_exists())
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$closure = function($a) { echo $a; };
|
||||
|
||||
var_dump(method_exists($closure, '__invoke')); // true
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
34
Zend/tests/bug52160.phpt
Normal file
34
Zend/tests/bug52160.phpt
Normal file
@ -0,0 +1,34 @@
|
||||
--TEST--
|
||||
Bug #52160 (Invalid E_STRICT redefined constructor error)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class bar {
|
||||
function __construct() { }
|
||||
static function bar() {
|
||||
var_dump(1);
|
||||
}
|
||||
}
|
||||
|
||||
bar::bar();
|
||||
|
||||
class foo {
|
||||
static function foo() {
|
||||
var_dump(2);
|
||||
}
|
||||
function __construct() { }
|
||||
}
|
||||
|
||||
foo::foo();
|
||||
|
||||
class baz {
|
||||
static function baz() {
|
||||
var_dump(3);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Strict Standards: Redefining already defined constructor for class foo in %s on line %d
|
||||
|
||||
Fatal error: Constructor baz::baz() cannot be static in %s on line %d
|
78
Zend/tests/bug52193.phpt
Normal file
78
Zend/tests/bug52193.phpt
Normal file
@ -0,0 +1,78 @@
|
||||
--TEST--
|
||||
Bug #52193 (converting closure to array yields empty array)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump((array) 1);
|
||||
var_dump((array) NULL);
|
||||
var_dump((array) new stdclass);
|
||||
var_dump($h = (array) function () { return 2; });
|
||||
var_dump($h[0]());
|
||||
|
||||
$i = function () use (&$h) {
|
||||
return $h;
|
||||
};
|
||||
|
||||
var_dump($x = (array)$i);
|
||||
var_dump($y = $x[0]);
|
||||
var_dump($y());
|
||||
|
||||
$items = range(1, 5);
|
||||
$func = function(){ return 'just a test'; };
|
||||
|
||||
array_splice($items, 0 , 4, $func);
|
||||
var_dump($items);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
array(0) {
|
||||
}
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Closure)#%d (0) {
|
||||
}
|
||||
}
|
||||
int(2)
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Closure)#%d (1) {
|
||||
["static"]=>
|
||||
array(1) {
|
||||
["h"]=>
|
||||
&array(1) {
|
||||
[0]=>
|
||||
object(Closure)#%d (0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
object(Closure)#%d (1) {
|
||||
["static"]=>
|
||||
array(1) {
|
||||
["h"]=>
|
||||
&array(1) {
|
||||
[0]=>
|
||||
object(Closure)#%d (0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Closure)#%d (0) {
|
||||
}
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
object(Closure)#%d (0) {
|
||||
}
|
||||
[1]=>
|
||||
int(5)
|
||||
}
|
12
Zend/tests/bug52237.phpt
Normal file
12
Zend/tests/bug52237.phpt
Normal file
@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Bug #52237 (Crash when passing the reference of the property of a non-object)
|
||||
--FILE--
|
||||
<?php
|
||||
$data = 'test';
|
||||
preg_match('//', '', $data->info);
|
||||
var_dump($data);
|
||||
?>
|
||||
--EXPECTF--
|
||||
|
||||
Warning: Attempt to modify property of non-object in %sbug52237.php on line 3
|
||||
string(4) "test"
|
35
Zend/tests/bug52361.phpt
Normal file
35
Zend/tests/bug52361.phpt
Normal file
@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
Bug #52361 (Throwing an exception in a destructor causes invalid catching)
|
||||
--FILE--
|
||||
<?php
|
||||
class aaa {
|
||||
public function __destruct() {
|
||||
try {
|
||||
throw new Exception(__CLASS__);
|
||||
} catch(Exception $ex) {
|
||||
echo "1. $ex\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
function bbb() {
|
||||
$a = new aaa();
|
||||
throw new Exception(__FUNCTION__);
|
||||
}
|
||||
try {
|
||||
bbb();
|
||||
echo "must be skipped !!!";
|
||||
} catch(Exception $ex) {
|
||||
echo "2. $ex\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
1. exception 'Exception' with message 'aaa' in %sbug52361.php:5
|
||||
Stack trace:
|
||||
#0 %sbug52361.php(16): aaa->__destruct()
|
||||
#1 %sbug52361.php(16): bbb()
|
||||
#2 {main}
|
||||
2. exception 'Exception' with message 'bbb' in %sbug52361.php:13
|
||||
Stack trace:
|
||||
#0 %sbug52361.php(16): bbb()
|
||||
#1 {main}
|
||||
|
19
Zend/tests/bug52484.phpt
Normal file
19
Zend/tests/bug52484.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Bug #52484 (__set() ignores setting properties with empty names)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
function __unset($prop) {
|
||||
unset($this->$prop);
|
||||
}
|
||||
}
|
||||
|
||||
$a = new A();
|
||||
$prop = null;
|
||||
|
||||
unset($a->$prop);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot access empty property in %s on line %d
|
19
Zend/tests/bug52484_2.phpt
Normal file
19
Zend/tests/bug52484_2.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Bug #52484.2 (__set() ignores setting properties with empty names)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
function __set($prop, $val) {
|
||||
$this->$prop = $val;
|
||||
}
|
||||
}
|
||||
|
||||
$a = new A();
|
||||
$prop = null;
|
||||
|
||||
$a->$prop = 2;
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot access empty property in %s on line %d
|
19
Zend/tests/bug52484_3.phpt
Normal file
19
Zend/tests/bug52484_3.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Bug #52484.3 (__set() ignores setting properties with empty names)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
function __get($prop) {
|
||||
var_dump($this->$prop);
|
||||
}
|
||||
}
|
||||
|
||||
$a = new A();
|
||||
$prop = null;
|
||||
|
||||
var_dump($a->$prop);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot access empty property in %s on line %d
|
20
Zend/tests/bug52508.phpt
Normal file
20
Zend/tests/bug52508.phpt
Normal file
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Bug #52508 (newline problem with parse_ini_file+INI_SCANNER_RAW)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$file = dirname(__FILE__) .'/bug52508.ini';
|
||||
|
||||
file_put_contents($file, "a = 1");
|
||||
|
||||
$ini_array = parse_ini_file($file, true, INI_SCANNER_RAW);
|
||||
var_dump($ini_array);
|
||||
|
||||
unlink($file);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
["a"]=>
|
||||
string(1) "1"
|
||||
}
|
83
Zend/tests/bug52614.phpt
Normal file
83
Zend/tests/bug52614.phpt
Normal file
@ -0,0 +1,83 @@
|
||||
--TEST--
|
||||
Bug #52614 (Memory leak when writing on uninitialized variable returned from method call)
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
public $a1;
|
||||
public $a2 = array();
|
||||
public $a3;
|
||||
public $o1;
|
||||
public $o2;
|
||||
|
||||
public function f1() {
|
||||
return $this->a1;
|
||||
}
|
||||
|
||||
public function f2() {
|
||||
return $this->a2;
|
||||
}
|
||||
|
||||
public function f3() {
|
||||
$this->a3 = array();
|
||||
return $this->a3;
|
||||
}
|
||||
|
||||
public function f4() {
|
||||
return $this->o1;
|
||||
}
|
||||
|
||||
public function f5() {
|
||||
$this->o2 = new stdClass;
|
||||
return $this->o2;
|
||||
}
|
||||
|
||||
public function &f6() {
|
||||
return $this->a1;
|
||||
}
|
||||
|
||||
public function f7(&$x) {
|
||||
$x = 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$foo = new foo;
|
||||
|
||||
$foo->f1()[0] = 1;
|
||||
var_dump($foo->a1);
|
||||
|
||||
$foo->f2()[0] = 1;
|
||||
var_dump($foo->a2);
|
||||
|
||||
$foo->f3()[0] = 1;
|
||||
var_dump($foo->a3);
|
||||
|
||||
$foo->f4()->a = 1;
|
||||
var_dump($foo->o1);
|
||||
|
||||
$foo->f5()->a = 1;
|
||||
var_dump($foo->o2);
|
||||
|
||||
$foo->a1[0] = 1;
|
||||
$foo->f7($foo->f6()[0]);
|
||||
var_dump($foo->a1[0]);
|
||||
$foo->f1()[0]++;
|
||||
var_dump($foo->a1[0]);
|
||||
$foo->f6()[0]++;
|
||||
var_dump($foo->a1[0]);
|
||||
--EXPECTF--
|
||||
NULL
|
||||
array(0) {
|
||||
}
|
||||
array(0) {
|
||||
}
|
||||
|
||||
Warning: Creating default object from empty value in %sbug52614.php on line 52
|
||||
NULL
|
||||
object(stdClass)#%d (1) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
}
|
||||
int(2)
|
||||
int(2)
|
||||
int(3)
|
16
Zend/tests/bug52879.phpt
Normal file
16
Zend/tests/bug52879.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Bug #52879 (Objects unreferenced in __get, __set, __isset or __unset can be freed too early)
|
||||
--FILE--
|
||||
<?php
|
||||
class MyClass {
|
||||
public $myRef;
|
||||
public function __set($property,$value) {
|
||||
$this->myRef = $value;
|
||||
}
|
||||
}
|
||||
$myGlobal=new MyClass($myGlobal);
|
||||
$myGlobal->myRef=&$myGlobal;
|
||||
$myGlobal->myNonExistentProperty="ok\n";
|
||||
echo $myGlobal;
|
||||
--EXPECT--
|
||||
ok
|
40
Zend/tests/bug52939.phpt
Normal file
40
Zend/tests/bug52939.phpt
Normal file
@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
Bug #52939 (zend_call_function_array does not respect ZEND_SEND_PREFER_REF)
|
||||
--FILE--
|
||||
<?php
|
||||
$ar1 = array("row1" => 2, "row2" => 1);
|
||||
var_dump(array_multisort($ar1));
|
||||
var_dump($ar1);
|
||||
|
||||
$ar1 = array("row1" => 2, "row2" => 1);
|
||||
$args = array(&$ar1);
|
||||
var_dump(call_user_func_array("array_multisort", $args));
|
||||
var_dump($ar1);
|
||||
|
||||
$ar1 = array("row1" => 2, "row2" => 1);
|
||||
$args = array($ar1);
|
||||
var_dump(call_user_func_array("array_multisort", $args));
|
||||
var_dump($ar1);
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
array(2) {
|
||||
["row2"]=>
|
||||
int(1)
|
||||
["row1"]=>
|
||||
int(2)
|
||||
}
|
||||
bool(true)
|
||||
array(2) {
|
||||
["row2"]=>
|
||||
int(1)
|
||||
["row1"]=>
|
||||
int(2)
|
||||
}
|
||||
bool(true)
|
||||
array(2) {
|
||||
["row1"]=>
|
||||
int(2)
|
||||
["row2"]=>
|
||||
int(1)
|
||||
}
|
23
Zend/tests/bug52940.phpt
Normal file
23
Zend/tests/bug52940.phpt
Normal file
@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Bug #52940 (call_user_func_array still allows call-time pass-by-reference)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo($a) {
|
||||
$a++;
|
||||
var_dump($a);
|
||||
}
|
||||
function bar(&$a) {
|
||||
$a++;
|
||||
var_dump($a);
|
||||
}
|
||||
$a = 1;
|
||||
call_user_func_array("foo", array(&$a));
|
||||
var_dump($a);
|
||||
call_user_func_array("bar", array(&$a));
|
||||
var_dump($a);
|
||||
?>
|
||||
--EXPECT--
|
||||
int(2)
|
||||
int(1)
|
||||
int(2)
|
||||
int(2)
|
19
Zend/tests/bug53305.phpt
Normal file
19
Zend/tests/bug53305.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Bug #53305 (E_NOTICE when defining a constant starts with __COMPILER_HALT_OFFSET__)
|
||||
--FILE--
|
||||
<?php
|
||||
error_reporting(E_ALL);
|
||||
|
||||
define('__COMPILER_HALT_OFFSET__1', 1);
|
||||
define('__COMPILER_HALT_OFFSET__2', 2);
|
||||
define('__COMPILER_HALT_OFFSET__', 3);
|
||||
define('__COMPILER_HALT_OFFSET__1'.chr(0), 4);
|
||||
|
||||
var_dump(__COMPILER_HALT_OFFSET__1);
|
||||
var_dump(constant('__COMPILER_HALT_OFFSET__1'.chr(0)));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Constant __COMPILER_HALT_OFFSET__ already defined in %s on line %d
|
||||
int(1)
|
||||
int(4)
|
17
Zend/tests/bug53347.phpt
Normal file
17
Zend/tests/bug53347.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Bug #53347 Segfault accessing static method
|
||||
--FILE--
|
||||
<?php class ezcConsoleOutput
|
||||
{
|
||||
protected static $color = array( 'gray' => 30 );
|
||||
|
||||
public static function isValidFormatCode( $type, $key )
|
||||
{
|
||||
return isset( self::${$type}[$key] );
|
||||
}
|
||||
}
|
||||
|
||||
var_dump( ezcConsoleOutput::isValidFormatCode( 'color', 'gray' ) );
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
33
Zend/tests/bug53511.phpt
Normal file
33
Zend/tests/bug53511.phpt
Normal file
@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
Bug #53511 (Exceptions are lost in case an exception is thrown in catch operator)
|
||||
--FILE--
|
||||
<?php
|
||||
class Foo {
|
||||
function __destruct() {
|
||||
throw new Exception("ops 1");
|
||||
}
|
||||
}
|
||||
|
||||
function test() {
|
||||
$e = new Foo();
|
||||
try {
|
||||
throw new Exception("ops 2");
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage()."\n";
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
echo "bug\n";
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught exception 'Exception' with message 'ops 2' in %sbug53511.php:11
|
||||
Stack trace:
|
||||
#0 %sbug53511.php(17): test()
|
||||
#1 {main}
|
||||
|
||||
Next exception 'Exception' with message 'ops 1' in %sbug53511.php:4
|
||||
Stack trace:
|
||||
#0 %sbug53511.php(12): Foo->__destruct()
|
||||
#1 %sbug53511.php(17): test()
|
||||
#2 {main}
|
||||
thrown in %sbug53511.php on line 4
|
31
Zend/tests/bug53629.phpt
Normal file
31
Zend/tests/bug53629.phpt
Normal file
@ -0,0 +1,31 @@
|
||||
--TEST--
|
||||
Bug #53629 (memory leak inside highlight_string())
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$str = '
|
||||
<?php
|
||||
class foo {
|
||||
public $bar = <<<EOT
|
||||
bar
|
||||
EOT;
|
||||
}
|
||||
?>
|
||||
';
|
||||
$str2 = '
|
||||
<?php
|
||||
var_dump(array(<<<EOD
|
||||
foobar!
|
||||
EOD
|
||||
));
|
||||
?>
|
||||
';
|
||||
|
||||
highlight_string($str, true);
|
||||
highlight_string($str2, true);
|
||||
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
10
Zend/tests/bug53632.phpt
Normal file
10
Zend/tests/bug53632.phpt
Normal file
@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
zend_strtod() hangs with 2.2250738585072011e-308
|
||||
--FILE--
|
||||
<?php
|
||||
$d = 2.2250738585072011e-308;
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Done
|
39
Zend/tests/bug53748.phpt
Normal file
39
Zend/tests/bug53748.phpt
Normal file
@ -0,0 +1,39 @@
|
||||
--TEST--
|
||||
Bug #53748 (Using traits lead to a segmentation fault)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
trait Singleton {
|
||||
protected static $instances=array();
|
||||
abstract protected function __construct($config);
|
||||
public static function getInstance($config) {
|
||||
if (!isset(self::$instances[$serialize = serialize($config)])) {
|
||||
self::$instances[$serialize] = new self($config);
|
||||
}
|
||||
return self::$instances[$serialize];
|
||||
}
|
||||
}
|
||||
|
||||
class MyHelloWorld {
|
||||
use Singleton;
|
||||
public function __construct($config)
|
||||
{
|
||||
var_dump( $config);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$o= myHelloWorld::getInstance(1);
|
||||
$o= myHelloWorld::getInstance(1);
|
||||
$o= myHelloWorld::getInstance(2);
|
||||
$o= myHelloWorld::getInstance(array(1=>2));
|
||||
$o= myHelloWorld::getInstance(array(1=>2));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
int(1)
|
||||
int(2)
|
||||
array(1) {
|
||||
[1]=>
|
||||
int(2)
|
||||
}
|
61
Zend/tests/bug53958.phpt
Normal file
61
Zend/tests/bug53958.phpt
Normal file
@ -0,0 +1,61 @@
|
||||
--TEST--
|
||||
Bug #53958 (Closures can't 'use' shared variables by value and by reference)
|
||||
--FILE--
|
||||
<?php
|
||||
// TEST 1
|
||||
$a = 1;
|
||||
$fn1 = function() use ($a) {echo "$a\n"; $a++;};
|
||||
$fn2 = function() use ($a) {echo "$a\n"; $a++;};
|
||||
$a = 5;
|
||||
$fn1(); // 1
|
||||
$fn2(); // 1
|
||||
$fn1(); // 1
|
||||
$fn2(); // 1
|
||||
|
||||
// TEST 2
|
||||
$b = 1;
|
||||
$fn1 = function() use (&$b) {echo "$b\n"; $b++;};
|
||||
$fn2 = function() use (&$b) {echo "$b\n"; $b++;};
|
||||
$b = 5;
|
||||
$fn1(); // 5
|
||||
$fn2(); // 6
|
||||
$fn1(); // 7
|
||||
$fn2(); // 8
|
||||
|
||||
// TEST 3
|
||||
$c = 1;
|
||||
$fn1 = function() use (&$c) {echo "$c\n"; $c++;};
|
||||
$fn2 = function() use ($c) {echo "$c\n"; $c++;};
|
||||
$c = 5;
|
||||
$fn1(); // 5
|
||||
$fn2(); // 1
|
||||
$fn1(); // 6
|
||||
$fn2(); // 1
|
||||
|
||||
// TEST 4
|
||||
$d = 1;
|
||||
$fn1 = function() use ($d) {echo "$d\n"; $d++;};
|
||||
$fn2 = function() use (&$d) {echo "$d\n"; $d++;};
|
||||
$d = 5;
|
||||
$fn1(); // 1
|
||||
$fn2(); // 5
|
||||
$fn1(); // 1
|
||||
$fn2(); // 6
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
5
|
||||
1
|
||||
6
|
||||
1
|
||||
1
|
||||
5
|
||||
1
|
||||
6
|
11
Zend/tests/bug53971.phpt
Normal file
11
Zend/tests/bug53971.phpt
Normal file
@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
Bug #53971 (isset() and empty() produce apparently spurious runtime error)
|
||||
--FILE--
|
||||
<?php
|
||||
$s = "";
|
||||
var_dump(isset($s[0][0]));
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
|
||||
|
31
Zend/tests/bug54013.phpt
Normal file
31
Zend/tests/bug54013.phpt
Normal file
@ -0,0 +1,31 @@
|
||||
--TEST--
|
||||
Bug #54013 (ReflectionParam for duplicate parameter contains garbage)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class a
|
||||
{
|
||||
function b($aaaaaaaa, $aaaaaaaa)
|
||||
{
|
||||
$params = func_get_args();
|
||||
}
|
||||
}
|
||||
|
||||
$c = new a;
|
||||
$c->b('waa?', 'meukee!');
|
||||
|
||||
$reflectionClass = new ReflectionClass($c);
|
||||
$params = $reflectionClass->getMethod('b')->getParameters();
|
||||
|
||||
var_dump($params[0], $params[1]);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(ReflectionParameter)#%d (1) {
|
||||
["name"]=>
|
||||
string(8) "aaaaaaaa"
|
||||
}
|
||||
object(ReflectionParameter)#%d (1) {
|
||||
["name"]=>
|
||||
string(8) "aaaaaaaa"
|
||||
}
|
58
Zend/tests/bug54039.phpt
Normal file
58
Zend/tests/bug54039.phpt
Normal file
@ -0,0 +1,58 @@
|
||||
--TEST--
|
||||
Bug #54039 (use() of static variables in lambda functions can break staticness)
|
||||
--FILE--
|
||||
<?php
|
||||
function test_1() {
|
||||
static $v = 0;
|
||||
++$v;
|
||||
echo "Outer function increments \$v to $v\n";
|
||||
$f = function() use($v) {
|
||||
echo "Inner function reckons \$v is $v\n";
|
||||
};
|
||||
return $f;
|
||||
}
|
||||
|
||||
$f = test_1(); $f();
|
||||
$f = test_1(); $f();
|
||||
|
||||
function test_2() {
|
||||
static $v = 0;
|
||||
$f = function() use($v) {
|
||||
echo "Inner function reckons \$v is $v\n";
|
||||
};
|
||||
++$v;
|
||||
echo "Outer function increments \$v to $v\n";
|
||||
return $f;
|
||||
}
|
||||
|
||||
$f = test_2(); $f();
|
||||
$f = test_2(); $f();
|
||||
|
||||
function test_3() {
|
||||
static $v = "";
|
||||
$v .= 'b';
|
||||
echo "Outer function catenates 'b' onto \$v to give $v\n";
|
||||
$f = function() use($v) {
|
||||
echo "Inner function reckons \$v is $v\n";
|
||||
};
|
||||
$v .= 'a';
|
||||
echo "Outer function catenates 'a' onto \$v to give $v\n";
|
||||
return $f;
|
||||
}
|
||||
$f = test_3(); $f();
|
||||
$f = test_3(); $f();
|
||||
--EXPECT--
|
||||
Outer function increments $v to 1
|
||||
Inner function reckons $v is 1
|
||||
Outer function increments $v to 2
|
||||
Inner function reckons $v is 2
|
||||
Outer function increments $v to 1
|
||||
Inner function reckons $v is 0
|
||||
Outer function increments $v to 2
|
||||
Inner function reckons $v is 1
|
||||
Outer function catenates 'b' onto $v to give b
|
||||
Outer function catenates 'a' onto $v to give ba
|
||||
Inner function reckons $v is b
|
||||
Outer function catenates 'b' onto $v to give bab
|
||||
Outer function catenates 'a' onto $v to give baba
|
||||
Inner function reckons $v is bab
|
17
Zend/tests/bug54262.phpt
Normal file
17
Zend/tests/bug54262.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Bug #54262 (Crash when assigning value to a dimension in a non-array)
|
||||
--FILE--
|
||||
<?php
|
||||
$a = '0';
|
||||
var_dump(isset($a['b']));
|
||||
$simpleString = preg_match('//', '', $a->a);
|
||||
$simpleString["wrong"] = "f";
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
|
||||
Warning: Attempt to modify property of non-object in %s/Zend/tests/bug54262.php on line 4
|
||||
|
||||
Warning: Cannot use a scalar value as an array in %s/Zend/tests/bug54262.php on line 5
|
||||
ok
|
17
Zend/tests/bug54265.phpt
Normal file
17
Zend/tests/bug54265.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Bug #54265 (crash when variable gets reassigned in error handler)
|
||||
--FILE--
|
||||
<?php
|
||||
function my_errorhandler($errno,$errormsg) {
|
||||
global $my_var;
|
||||
$my_var = 0;
|
||||
echo "EROOR: $errormsg\n";
|
||||
}
|
||||
set_error_handler("my_errorhandler");
|
||||
$my_var = str_repeat("A",$my_var[0]->errormsg = "xyz");
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
EROOR: Creating default object from empty value
|
||||
ok
|
||||
|
35
Zend/tests/bug54268.phpt
Normal file
35
Zend/tests/bug54268.phpt
Normal file
@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
Bug #54268 (Double free when destroy_zend_class fails)
|
||||
--INI--
|
||||
memory_limit=8M
|
||||
--SKIPIF--
|
||||
<?php
|
||||
$zend_mm_enabled = getenv("USE_ZEND_ALLOC");
|
||||
if ($zend_mm_enabled === "0") {
|
||||
die("skip Zend MM disabled");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
class DestructableObject
|
||||
{
|
||||
public function __destruct()
|
||||
{
|
||||
DestructableObject::__destruct();
|
||||
}
|
||||
}
|
||||
class DestructorCreator
|
||||
{
|
||||
public function __destruct()
|
||||
{
|
||||
$this->test = new DestructableObject;
|
||||
}
|
||||
}
|
||||
class Test
|
||||
{
|
||||
public static $mystatic;
|
||||
}
|
||||
$x = new Test();
|
||||
Test::$mystatic = new DestructorCreator();
|
||||
--EXPECTF--
|
||||
Fatal error: Allowed memory size of %s bytes exhausted%s(tried to allocate %s bytes) in %s on line %d
|
39
Zend/tests/bug54358.phpt
Normal file
39
Zend/tests/bug54358.phpt
Normal file
@ -0,0 +1,39 @@
|
||||
--TEST--
|
||||
Bug #54358 (Closure, use and reference)
|
||||
--FILE--
|
||||
<?php
|
||||
class asserter {
|
||||
public function call($function) {
|
||||
}
|
||||
}
|
||||
|
||||
$asserter = new asserter();
|
||||
|
||||
$closure = function() use ($asserter, &$function) {
|
||||
$asserter->call($function = 'md5');
|
||||
};
|
||||
|
||||
$closure();
|
||||
|
||||
var_dump($function);
|
||||
|
||||
$closure = function() use ($asserter, $function) {
|
||||
$asserter->call($function);
|
||||
};
|
||||
|
||||
$closure();
|
||||
|
||||
var_dump($function);
|
||||
|
||||
$closure = function() use ($asserter, $function) {
|
||||
$asserter->call($function);
|
||||
};
|
||||
|
||||
$closure();
|
||||
|
||||
var_dump($function);
|
||||
?>
|
||||
--EXPECT--
|
||||
string(3) "md5"
|
||||
string(3) "md5"
|
||||
string(3) "md5"
|
24
Zend/tests/bug54367.phpt
Normal file
24
Zend/tests/bug54367.phpt
Normal file
@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
Bug #54367 (Use of closure causes problem in ArrayAccess)
|
||||
--FILE--
|
||||
<?php
|
||||
class MyObjet implements ArrayAccess
|
||||
{
|
||||
public function offsetSet($offset, $value) { }
|
||||
public function offsetExists($offset) { }
|
||||
public function offsetUnset($offset) { }
|
||||
|
||||
public function offsetGet ($offset)
|
||||
{
|
||||
return function ($var) use ($offset) { // here is the problem
|
||||
var_dump($offset, $var);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
$a = new MyObjet();
|
||||
echo $a['p']('foo');
|
||||
?>
|
||||
--EXPECT--
|
||||
string(1) "p"
|
||||
string(3) "foo"
|
23
Zend/tests/bug54372.phpt
Normal file
23
Zend/tests/bug54372.phpt
Normal file
@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Bug #54372 (Crash accessing global object itself returned from its __get() handle)
|
||||
--FILE--
|
||||
<?php
|
||||
class test_class
|
||||
{
|
||||
public function __get($name)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function b()
|
||||
{
|
||||
echo "ok\n";
|
||||
}
|
||||
}
|
||||
|
||||
global $test3;
|
||||
$test3 = new test_class();
|
||||
$test3->a->b();
|
||||
?>
|
||||
--EXPECT--
|
||||
ok
|
15
Zend/tests/bug54585.phpt
Normal file
15
Zend/tests/bug54585.phpt
Normal file
@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
Bug #54585 (track_errors causes segfault)
|
||||
--INI--
|
||||
track_errors=On
|
||||
--FILE--
|
||||
<?php
|
||||
function testing($source) {
|
||||
unset($source[$cos]);
|
||||
}
|
||||
testing($_GET);
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Undefined variable: cos in %sbug54585.php on line 3
|
||||
ok
|
@ -28,9 +28,9 @@ foo::BAZ();
|
||||
--EXPECT--
|
||||
nonstatic
|
||||
string(6) "fOoBaR"
|
||||
static
|
||||
nonstatic
|
||||
string(6) "foOBAr"
|
||||
static
|
||||
nonstatic
|
||||
string(6) "fOOBAr"
|
||||
static
|
||||
string(3) "bAr"
|
||||
|
@ -30,5 +30,5 @@ a::Foo();
|
||||
--EXPECT--
|
||||
__callstatic: Test
|
||||
__call: Test
|
||||
__callstatic: Bar
|
||||
__call: Bar
|
||||
__callstatic: Foo
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Checking if exists interface, abstract and final class
|
||||
Checking if exists interface, trait, abstract and final class
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
@ -9,12 +9,16 @@ abstract class b { }
|
||||
|
||||
final class c { }
|
||||
|
||||
trait d {}
|
||||
|
||||
var_dump(class_exists('a'));
|
||||
var_dump(class_exists('b'));
|
||||
var_dump(class_exists('c'));
|
||||
var_dump(class_exists('d'));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(false)
|
||||
|
74
Zend/tests/closure_005.phpt
Normal file
74
Zend/tests/closure_005.phpt
Normal file
@ -0,0 +1,74 @@
|
||||
--TEST--
|
||||
Closure 005: Lambda inside class, lifetime of $this
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
private $x;
|
||||
|
||||
function __construct($x) {
|
||||
$this->x = $x;
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
echo "Destroyed\n";
|
||||
}
|
||||
|
||||
function getIncer($val) {
|
||||
return function() use ($val) {
|
||||
$this->x += $val;
|
||||
};
|
||||
}
|
||||
|
||||
function getPrinter() {
|
||||
return function() {
|
||||
echo $this->x."\n";
|
||||
};
|
||||
}
|
||||
|
||||
function getError() {
|
||||
return static function() {
|
||||
echo $this->x."\n";
|
||||
};
|
||||
}
|
||||
|
||||
function printX() {
|
||||
echo $this->x."\n";
|
||||
}
|
||||
}
|
||||
|
||||
$a = new A(3);
|
||||
$incer = $a->getIncer(2);
|
||||
$printer = $a->getPrinter();
|
||||
$error = $a->getError();
|
||||
|
||||
$a->printX();
|
||||
$printer();
|
||||
$incer();
|
||||
$a->printX();
|
||||
$printer();
|
||||
|
||||
unset($a);
|
||||
|
||||
$incer();
|
||||
$printer();
|
||||
|
||||
unset($incer);
|
||||
$printer();
|
||||
|
||||
unset($printer);
|
||||
|
||||
$error();
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
3
|
||||
3
|
||||
5
|
||||
5
|
||||
7
|
||||
7
|
||||
Destroyed
|
||||
|
||||
Fatal error: Using $this when not in object context in %sclosure_005.php on line 28
|
38
Zend/tests/closure_007.phpt
Normal file
38
Zend/tests/closure_007.phpt
Normal file
@ -0,0 +1,38 @@
|
||||
--TEST--
|
||||
Closure 007: Nested lambdas in classes
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
private $x = 0;
|
||||
|
||||
function getClosureGetter () {
|
||||
return function () {
|
||||
return function () {
|
||||
$this->x++;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function printX () {
|
||||
echo $this->x."\n";
|
||||
}
|
||||
}
|
||||
|
||||
$a = new A;
|
||||
$a->printX();
|
||||
$getClosure = $a->getClosureGetter();
|
||||
$a->printX();
|
||||
$closure = $getClosure();
|
||||
$a->printX();
|
||||
$closure();
|
||||
$a->printX();
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
Done
|
@ -23,27 +23,18 @@ var_dump($y()->test);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(foo)#%d (%d) {
|
||||
object(foo)#%d (2) {
|
||||
["test":"foo":private]=>
|
||||
int(3)
|
||||
["a"]=>
|
||||
object(Closure)#%d (1) {
|
||||
object(Closure)#%d (2) {
|
||||
["static"]=>
|
||||
array(1) {
|
||||
["a"]=>
|
||||
&object(foo)#%d (2) {
|
||||
["test":"foo":private]=>
|
||||
int(3)
|
||||
["a"]=>
|
||||
object(Closure)#%d (1) {
|
||||
["static"]=>
|
||||
array(1) {
|
||||
["a"]=>
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
}
|
||||
*RECURSION*
|
||||
}
|
||||
["this"]=>
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
|
@ -1,16 +1,26 @@
|
||||
--TEST--
|
||||
Closure 024: Trying to clone the Closure object
|
||||
Closure 024: Clone the Closure object
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = function () {
|
||||
return clone function () {
|
||||
return 1;
|
||||
};
|
||||
};
|
||||
$a = 1;
|
||||
$c = function($add) use(&$a) { return $a+$add; };
|
||||
|
||||
$a();
|
||||
$cc = clone $c;
|
||||
|
||||
echo $c(10)."\n";
|
||||
echo $cc(10)."\n";
|
||||
|
||||
$a++;
|
||||
|
||||
echo $c(10)."\n";
|
||||
echo $cc(10)."\n";
|
||||
|
||||
echo "Done.\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Trying to clone an uncloneable object of class Closure in %s on line %d
|
||||
11
|
||||
11
|
||||
12
|
||||
12
|
||||
Done.
|
@ -32,7 +32,9 @@ object(foo)#%d (1) {
|
||||
["a"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Closure)#%d (0) {
|
||||
object(Closure)#%d (1) {
|
||||
["this"]=>
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -41,7 +43,12 @@ int(1)
|
||||
string(1) "a"
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Closure)#%d (0) {
|
||||
object(Closure)#%d (1) {
|
||||
["this"]=>
|
||||
object(foo)#%d (1) {
|
||||
["a"]=>
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
}
|
||||
int(1)
|
||||
|
@ -9,17 +9,11 @@ var_dump($a);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
object(Closure)#1 (1) {
|
||||
object(Closure)#%d (1) {
|
||||
["static"]=>
|
||||
array(1) {
|
||||
["a"]=>
|
||||
&object(Closure)#1 (1) {
|
||||
["static"]=>
|
||||
array(1) {
|
||||
["a"]=>
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
===DONE===
|
||||
|
@ -18,14 +18,8 @@ var_dump($x());
|
||||
object(Closure)#%d (1) {
|
||||
["static"]=>
|
||||
array(1) {
|
||||
[%u|b%"x"]=>
|
||||
&object(Closure)#%d (1) {
|
||||
["static"]=>
|
||||
array(1) {
|
||||
[%u|b%"x"]=>
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
["x"]=>
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
int(1)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user