mirror of
https://github.com/php/php-src.git
synced 2024-11-24 10:24:11 +08:00
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport
Conflicts: Zend/zend_vm_def.h Zend/zend_vm_execute.h
This commit is contained in:
commit
6517ed0215
202
INSTALL
202
INSTALL
@ -24,6 +24,7 @@ Installing PHP
|
||||
+ Installing a PHP extension on Windows
|
||||
+ Compiling shared PECL extensions with the pecl command
|
||||
+ Compiling shared PECL extensions with phpize
|
||||
+ php-config
|
||||
+ Compiling PECL extensions statically into PHP
|
||||
* Problems?
|
||||
+ Read the FAQ
|
||||
@ -83,7 +84,7 @@ General Installation Considerations
|
||||
With PHP you can also write desktop GUI applications using the PHP-GTK
|
||||
extension. This is a completely different approach than writing web
|
||||
pages, as you do not output any HTML, but manage windows and objects
|
||||
within them. For more information about PHP-GTK, please » visit the
|
||||
within them. For more information about PHP-GTK, please » visit the
|
||||
site dedicated to this extension. PHP-GTK is not included in the
|
||||
official PHP distribution.
|
||||
|
||||
@ -92,9 +93,9 @@ General Installation Considerations
|
||||
will also find information on the command line executable in the
|
||||
following sections.
|
||||
|
||||
PHP source code and binary distributions for Windows can be found at »
|
||||
http://www.php.net/downloads.php. We recommend you to choose a » mirror
|
||||
nearest to you for downloading the distributions.
|
||||
PHP source code and binary distributions for Windows can be found at
|
||||
» http://www.php.net/downloads.php. We recommend you to choose a
|
||||
» mirror nearest to you for downloading the distributions.
|
||||
__________________________________________________________________
|
||||
__________________________________________________________________
|
||||
|
||||
@ -140,9 +141,9 @@ Table of Contents
|
||||
* A web server
|
||||
* Any module specific components (such as GD, PDF libs, etc.)
|
||||
|
||||
When building directly from SVN sources or after custom modifications
|
||||
When building directly from Git sources or after custom modifications
|
||||
you might also need:
|
||||
* autoconf: 2.13
|
||||
* autoconf: 2.13+ (for PHP < 5.4.0), 2.59+ (for PHP >= 5.4.0)
|
||||
* automake: 1.4+
|
||||
* libtool: 1.4.x+ (except 1.4.2)
|
||||
* re2c: Version 0.13.4 or newer
|
||||
@ -375,12 +376,12 @@ Apache 2.x on Unix systems
|
||||
For information on why, read the related FAQ entry on using Apache2
|
||||
with a threaded MPM
|
||||
|
||||
The » Apache Documentation is the most authoritative source of
|
||||
The » Apache Documentation is the most authoritative source of
|
||||
information on the Apache 2.x server. More information about
|
||||
installation options for Apache may be found there.
|
||||
|
||||
The most recent version of Apache HTTP Server may be obtained from »
|
||||
Apache download site, and a fitting PHP version from the above
|
||||
The most recent version of Apache HTTP Server may be obtained from
|
||||
» Apache download site, and a fitting PHP version from the above
|
||||
mentioned places. This quick guide covers only the basics to get
|
||||
started with Apache 2.x and PHP. For more information read the » Apache
|
||||
Documentation. The version numbers have been omitted here, to ensure
|
||||
@ -498,7 +499,7 @@ service httpd restart
|
||||
|
||||
This should not be undertaken without being aware of the consequences
|
||||
of this decision, and having at least a fair understanding of the
|
||||
implications. The Apache documentation regarding » MPM-Modules
|
||||
implications. The Apache documentation regarding » MPM-Modules
|
||||
discusses MPMs in a great deal more detail.
|
||||
|
||||
Note:
|
||||
@ -520,7 +521,7 @@ Lighttpd 1.4 on Unix systems
|
||||
This section contains notes and hints specific to Lighttpd 1.4 installs
|
||||
of PHP on Unix systems.
|
||||
|
||||
Please use the » Lighttpd trac to learn how to install Lighttpd
|
||||
Please use the » Lighttpd trac to learn how to install Lighttpd
|
||||
properly before continuing.
|
||||
|
||||
Fastcgi is the preferred SAPI to connect PHP and Lighttpd. Fastcgi is
|
||||
@ -627,15 +628,15 @@ Sun, iPlanet and Netscape servers on Sun Solaris
|
||||
current web servers read the note about subrequests.
|
||||
|
||||
You can find more information about setting up PHP for the Netscape
|
||||
Enterprise Server (NES) here: »
|
||||
http://benoit.noss.free.fr/php/install-php4.html
|
||||
Enterprise Server (NES) here:
|
||||
» http://benoit.noss.free.fr/php/install-php4.html
|
||||
|
||||
To build PHP with Sun JSWS/Sun ONE WS/iPlanet/Netscape web servers,
|
||||
enter the proper install directory for the --with-nsapi=[DIR] option.
|
||||
The default directory is usually /opt/netscape/suitespot/. Please also
|
||||
read /php-xxx-version/sapi/nsapi/nsapi-readme.txt.
|
||||
|
||||
1. Install the following packages from » http://www.sunfreeware.com/
|
||||
1. Install the following packages from » http://www.sunfreeware.com/
|
||||
or another download site:
|
||||
+ autoconf-2.13
|
||||
+ automake-1.4
|
||||
@ -837,7 +838,7 @@ Testing
|
||||
Using Variables
|
||||
|
||||
Some server supplied environment variables are not defined in the
|
||||
current » CGI/1.1 specification. Only the following variables are
|
||||
current » CGI/1.1 specification. Only the following variables are
|
||||
defined there: AUTH_TYPE, CONTENT_LENGTH, CONTENT_TYPE,
|
||||
GATEWAY_INTERFACE, PATH_INFO, PATH_TRANSLATED, QUERY_STRING,
|
||||
REMOTE_ADDR, REMOTE_HOST, REMOTE_IDENT, REMOTE_USER, REQUEST_METHOD,
|
||||
@ -855,20 +856,20 @@ HP-UX specific installation notes
|
||||
There are two main options for installing PHP on HP-UX systems. Either
|
||||
compile it, or install a pre-compiled binary.
|
||||
|
||||
Official pre-compiled packages are located here: »
|
||||
http://software.hp.com/
|
||||
Official pre-compiled packages are located here:
|
||||
» http://software.hp.com/
|
||||
|
||||
Until this manual section is rewritten, the documentation about
|
||||
compiling PHP (and related extensions) on HP-UX systems has been
|
||||
removed. For now, consider reading the following external resource: »
|
||||
Building Apache and PHP on HP-UX 11.11
|
||||
removed. For now, consider reading the following external resource:
|
||||
» Building Apache and PHP on HP-UX 11.11
|
||||
__________________________________________________________________
|
||||
__________________________________________________________________
|
||||
|
||||
OpenBSD installation notes
|
||||
|
||||
This section contains notes and hints specific to installing PHP on »
|
||||
OpenBSD 3.6.
|
||||
This section contains notes and hints specific to installing PHP on
|
||||
» OpenBSD 3.6.
|
||||
|
||||
Using Binary Packages
|
||||
|
||||
@ -900,12 +901,12 @@ Using Binary Packages
|
||||
(install the PEAR libraries)
|
||||
# pkg_add php4-pear-4.3.8.tgz
|
||||
|
||||
Read the » packages(7) manual page for more information about binary
|
||||
Read the » packages(7) manual page for more information about binary
|
||||
packages on OpenBSD.
|
||||
|
||||
Using Ports
|
||||
|
||||
You can also compile up PHP from source using the » ports tree.
|
||||
You can also compile up PHP from source using the » ports tree.
|
||||
However, this is only recommended for users familiar with OpenBSD. The
|
||||
PHP 4 port is split into two sub-directories: core and extensions. The
|
||||
extensions directory generates sub-packages for all of the supported
|
||||
@ -926,7 +927,7 @@ Common Problems
|
||||
automatically installs into the correct chroot directories, so no
|
||||
special modification is needed there. More information on the
|
||||
OpenBSD Apache is available in the » OpenBSD FAQ.
|
||||
* The OpenBSD 3.6 package for the » gd extension requires XFree86 to
|
||||
* The OpenBSD 3.6 package for the » gd extension requires XFree86 to
|
||||
be installed. If you do not wish to use some of the font features
|
||||
that require X11, install the php4-gd-4.3.8-no_x11.tgz package
|
||||
instead.
|
||||
@ -951,18 +952,26 @@ Required software
|
||||
|
||||
Solaris installs often lack C compilers and their related tools. Read
|
||||
this FAQ for information on why using GNU versions for some of these
|
||||
tools is necessary. The required software is as follows:
|
||||
tools is necessary.
|
||||
|
||||
For unpacking the PHP distribution you need
|
||||
* tar
|
||||
* gzip or
|
||||
* bzip2
|
||||
|
||||
For compiling PHP you need
|
||||
* gcc (recommended, other C compilers may work)
|
||||
* make
|
||||
* flex
|
||||
* GNU sed
|
||||
|
||||
For building extra extensions or hacking the code of PHP you might also
|
||||
need
|
||||
* flex (up to PHP 5.2)
|
||||
* re2c
|
||||
* bison
|
||||
* m4
|
||||
* autoconf
|
||||
* automake
|
||||
* perl
|
||||
* gzip
|
||||
* tar
|
||||
* GNU sed
|
||||
|
||||
In addition, you will need to install (and possibly compile) any
|
||||
additional software specific to your configuration, such as Oracle or
|
||||
@ -971,14 +980,16 @@ Required software
|
||||
Using Packages
|
||||
|
||||
You can simplify the Solaris install process by using pkgadd to install
|
||||
most of your needed components.
|
||||
most of your needed components. The Image Packaging System (IPS) for
|
||||
Solaris 11 Express also contains most of the required components for
|
||||
installation using the pkg command.
|
||||
__________________________________________________________________
|
||||
__________________________________________________________________
|
||||
|
||||
Debian GNU/Linux installation notes
|
||||
|
||||
This section contains notes and hints specific to installing PHP on »
|
||||
Debian GNU/Linux.
|
||||
This section contains notes and hints specific to installing PHP on
|
||||
» Debian GNU/Linux.
|
||||
Warning
|
||||
|
||||
Unofficial builds from third-parties are not supported here. Any bugs
|
||||
@ -1205,6 +1216,7 @@ Table of Contents
|
||||
* Installing a PHP extension on Windows
|
||||
* Compiling shared PECL extensions with the pecl command
|
||||
* Compiling shared PECL extensions with phpize
|
||||
* php-config
|
||||
* Compiling PECL extensions statically into PHP
|
||||
__________________________________________________________________
|
||||
|
||||
@ -1227,8 +1239,8 @@ Introduction to PECL Installations
|
||||
To this php.ini file, or through the use of the dl() function.
|
||||
|
||||
When building PHP modules, it's important to have known-good versions
|
||||
of the required tools (autoconf, automake, libtool, etc.) See the »
|
||||
Anonymous SVN Instructions for details on the required tools, and
|
||||
of the required tools (autoconf, automake, libtool, etc.) See the
|
||||
» Anonymous Git Instructions for details on the required tools, and
|
||||
required versions.
|
||||
__________________________________________________________________
|
||||
__________________________________________________________________
|
||||
@ -1247,7 +1259,7 @@ Downloading PECL extensions
|
||||
the PECL web site are available for download and installation using
|
||||
the » pecl command. Specific revisions may also be specified.
|
||||
* SVN Most PECL extensions also reside in SVN. A web-based view may
|
||||
be seen at » http://svn.php.net/viewvc/pecl/. To download straight
|
||||
be seen at » http://svn.php.net/viewvc/pecl/. To download straight
|
||||
from SVN, the following sequence of commands may be used:
|
||||
$ svn checkout http://svn.php.net/repository/pecl/extname/trunk
|
||||
extname
|
||||
@ -1279,7 +1291,7 @@ Where to find an extension?
|
||||
|
||||
PHP extensions are usually called "php_*.dll" (where the star
|
||||
represents the name of the extension) and they are located under the
|
||||
"PHP\ext" ("PHP\extensions" in PHP4) folder.
|
||||
"PHP\ext" ("PHP\extensions" in PHP 4) folder.
|
||||
|
||||
PHP ships with the extensions most useful to the majority of
|
||||
developers. They are called "core" extensions.
|
||||
@ -1365,7 +1377,7 @@ Resolving problems
|
||||
|
||||
Compiling shared PECL extensions with the pecl command
|
||||
|
||||
PECL makes it easy to create shared PHP extensions. Using the » pecl
|
||||
PECL makes it easy to create shared PHP extensions. Using the » pecl
|
||||
command, do the following:
|
||||
|
||||
$ pecl install extname
|
||||
@ -1424,6 +1436,51 @@ $ make
|
||||
__________________________________________________________________
|
||||
__________________________________________________________________
|
||||
|
||||
php-config
|
||||
|
||||
php-config is a simple shell script for obtaining information about the
|
||||
installed PHP configuration.
|
||||
|
||||
When compiling extensions, if you have multiple PHP versions installed,
|
||||
you may specify for which installation you'd like to build by using the
|
||||
--with-php-config option during configuration, specifying the path of
|
||||
the respective php-config script.
|
||||
|
||||
The list of command line options provided by the php-config script can
|
||||
be queried anytime by running php-config with the -h switch:
|
||||
Usage: /usr/local/bin/php-config [OPTION]
|
||||
Options:
|
||||
--prefix [...]
|
||||
--includes [...]
|
||||
--ldflags [...]
|
||||
--libs [...]
|
||||
--extension-dir [...]
|
||||
--include-dir [...]
|
||||
--php-binary [...]
|
||||
--php-sapis [...]
|
||||
--configure-options [...]
|
||||
--version [...]
|
||||
--vernum [...]
|
||||
|
||||
CAPTION: Command line options
|
||||
|
||||
Option Description
|
||||
--prefix Directory prefix where PHP is installed, e.g. /usr/local
|
||||
--includes List of -I options with all include files
|
||||
--ldflags LD Flags which PHP was compiled with
|
||||
--libs Extra libraries which PHP was compiled with
|
||||
--extension-dir Directory where extensions are searched by default
|
||||
--include-dir Directory prefix where header files are installed by
|
||||
default
|
||||
--php-binary Full path to php CLI or CGI binary
|
||||
--php-sapis Show all SAPI modules available
|
||||
--configure-options Configure options to recreate configuration of
|
||||
current PHP installation
|
||||
--version PHP version
|
||||
--vernum PHP version as integer
|
||||
__________________________________________________________________
|
||||
__________________________________________________________________
|
||||
|
||||
Compiling PECL extensions statically into PHP
|
||||
|
||||
You might find that you need to build a PECL extension statically into
|
||||
@ -1485,11 +1542,11 @@ Other problems
|
||||
If you are still stuck, someone on the PHP installation mailing list
|
||||
may be able to help you. You should check out the archive first, in
|
||||
case someone already answered someone else who had the same problem as
|
||||
you. The archives are available from the support page on »
|
||||
http://www.php.net/support.php. To subscribe to the PHP installation
|
||||
mailing list, send an empty mail to »
|
||||
php-install-subscribe@lists.php.net. The mailing list address is »
|
||||
php-install@lists.php.net.
|
||||
you. The archives are available from the support page on
|
||||
» http://www.php.net/support.php. To subscribe to the PHP installation
|
||||
mailing list, send an empty mail to
|
||||
» php-install-subscribe@lists.php.net. The mailing list address is
|
||||
» php-install@lists.php.net.
|
||||
|
||||
If you want to get help on the mailing list, please try to be precise
|
||||
and give the necessary details about your environment (which operating
|
||||
@ -1504,11 +1561,11 @@ Bug reports
|
||||
If you think you have found a bug in PHP, please report it. The PHP
|
||||
developers probably don't know about it, and unless you report it,
|
||||
chances are it won't be fixed. You can report bugs using the
|
||||
bug-tracking system at » http://bugs.php.net/. Please do not send bug
|
||||
bug-tracking system at » http://bugs.php.net/. Please do not send bug
|
||||
reports in mailing list or personal letters. The bug system is also
|
||||
suitable to submit feature requests.
|
||||
|
||||
Read the » How to report a bug document before submitting any bug
|
||||
Read the » How to report a bug document before submitting any bug
|
||||
reports!
|
||||
__________________________________________________________________
|
||||
__________________________________________________________________
|
||||
@ -1528,14 +1585,14 @@ The configuration file
|
||||
|
||||
The configuration file (php.ini) is read when PHP starts up. For the
|
||||
server module versions of PHP, this happens only once when the web
|
||||
server is started. For the CGI and CLI version, it happens on every
|
||||
server is started. For the CGI and CLI versions, it happens on every
|
||||
invocation.
|
||||
|
||||
php.ini is searched in these locations (in order):
|
||||
php.ini is searched for in these locations (in order):
|
||||
* SAPI module specific location (PHPIniDir directive in Apache 2, -c
|
||||
command line option in CGI and CLI, php_ini parameter in NSAPI,
|
||||
PHP_INI_PATH environment variable in THTTPD)
|
||||
* The PHPRC environment variable. Before PHP 5.2.0 this was checked
|
||||
* The PHPRC environment variable. Before PHP 5.2.0, this was checked
|
||||
after the registry key mentioned below.
|
||||
* As of PHP 5.2.0, the location of the php.ini file can be set for
|
||||
different versions of PHP. The following registry keys are examined
|
||||
@ -1543,33 +1600,33 @@ The configuration file
|
||||
[HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y] and
|
||||
[HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x], where x, y and z mean the PHP
|
||||
major, minor and release versions. If there is a value for
|
||||
IniFilePath in these keys, then the first one found will be used as
|
||||
the location of the php.ini (Windows only).
|
||||
IniFilePath in any of these keys, the first one found will be used
|
||||
as the location of the php.ini (Windows only).
|
||||
* [HKEY_LOCAL_MACHINE\SOFTWARE\PHP], value of IniFilePath (Windows
|
||||
only).
|
||||
* Current working directory (except CLI)
|
||||
* Current working directory (except CLI).
|
||||
* The web server's directory (for SAPI modules), or directory of PHP
|
||||
(otherwise in Windows)
|
||||
(otherwise in Windows).
|
||||
* Windows directory (C:\windows or C:\winnt) (for Windows), or
|
||||
--with-config-file-path compile time option
|
||||
--with-config-file-path compile time option.
|
||||
|
||||
If php-SAPI.ini exists (where SAPI is used SAPI, so the filename is
|
||||
e.g. php-cli.ini or php-apache.ini), it's used instead of php.ini. SAPI
|
||||
name can be determined by php_sapi_name().
|
||||
If php-SAPI.ini exists (where SAPI is the SAPI in use, so, for example,
|
||||
php-cli.ini or php-apache.ini), it is used instead of php.ini. The SAPI
|
||||
name can be determined with php_sapi_name().
|
||||
|
||||
Note:
|
||||
|
||||
The Apache web server changes the directory to root at startup
|
||||
The Apache web server changes the directory to root at startup,
|
||||
causing PHP to attempt to read php.ini from the root filesystem if
|
||||
it exists.
|
||||
|
||||
The php.ini directives handled by extensions are documented
|
||||
respectively on the pages of the extensions themselves. The list of the
|
||||
core directives is available in the appendix. Probably not all PHP
|
||||
directives are documented in the manual though. For a complete list of
|
||||
The php.ini directives handled by extensions are documented on the
|
||||
respective pages of the extensions themselves. A list of the core
|
||||
directives is available in the appendix. Not all PHP directives are
|
||||
necessarily documented in this manual: for a complete list of
|
||||
directives available in your PHP version, please read your well
|
||||
commented php.ini file. Alternatively, you may find the » the latest
|
||||
php.ini from SVN helpful too.
|
||||
commented php.ini file. Alternatively, you may find » the latest
|
||||
php.ini from Git helpful too.
|
||||
|
||||
Example #1 php.ini example
|
||||
; any text on a line after an unquoted semicolon (;) is ignored
|
||||
@ -1635,12 +1692,13 @@ Where a configuration setting may be set
|
||||
|
||||
CAPTION: Definition of PHP_INI_* modes
|
||||
|
||||
Mode Value Meaning
|
||||
PHP_INI_USER 1 Entry can be set in user scripts (like with ini_set())
|
||||
or in the Windows registry
|
||||
PHP_INI_PERDIR 6 Entry can be set in php.ini, .htaccess or httpd.conf
|
||||
PHP_INI_SYSTEM 4 Entry can be set in php.ini or httpd.conf
|
||||
PHP_INI_ALL 7 Entry can be set anywhere
|
||||
Mode Meaning
|
||||
PHP_INI_USER Entry can be set in user scripts (like with ini_set()) or
|
||||
in the Windows registry. Since PHP 5.3, entry can be set in .user.ini
|
||||
PHP_INI_PERDIR Entry can be set in php.ini, .htaccess, httpd.conf or
|
||||
.user.ini (since PHP 5.3)
|
||||
PHP_INI_SYSTEM Entry can be set in php.ini or httpd.conf
|
||||
PHP_INI_ALL Entry can be set anywhere
|
||||
__________________________________________________________________
|
||||
__________________________________________________________________
|
||||
|
||||
@ -1788,13 +1846,9 @@ Installation
|
||||
each request to play in, further weaknesses are introduced into
|
||||
PHP's system.
|
||||
|
||||
If you feel you have to use a threaded MPM, look at a FastCGI
|
||||
If you want to use a threaded MPM, look at a FastCGI
|
||||
configuration where PHP is running in its own memory space.
|
||||
|
||||
And finally, this warning against using a threaded MPM is not as
|
||||
strong for Windows systems because most libraries on that
|
||||
platform tend to be threadsafe.
|
||||
|
||||
Unix/Windows: Where should my php.ini file be located?
|
||||
By default on Unix it should be in /usr/local/lib which is
|
||||
<install-path>/lib. Most people will want to change this at
|
||||
|
1
NEWS
1
NEWS
@ -5,7 +5,6 @@ PHP NEWS
|
||||
- General improvements:
|
||||
. Implemented 'finally' keyword (https://wiki.php.net/rfc/finally). (Laruence)
|
||||
. Drop Windows XP and 2003 support. (Pierre)
|
||||
. World domination
|
||||
. Improve set_exception_handler while doing reset.(Laruence)
|
||||
. Support constant array/string dereferencing. (Laruence)
|
||||
. Add support for using empty() on the result of function calls and
|
||||
|
32
Zend/tests/bug62358.phpt
Normal file
32
Zend/tests/bug62358.phpt
Normal file
@ -0,0 +1,32 @@
|
||||
--TEST--
|
||||
Bug #62358 (Segfault when using traits a lot)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (getenv("USE_ZEND_ALLOC") !== "0") {
|
||||
die("skip Need Zend MM enabled");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
trait T {
|
||||
public function foo() {
|
||||
echo "from T";
|
||||
}
|
||||
}
|
||||
|
||||
interface I {
|
||||
public function foo();
|
||||
}
|
||||
|
||||
abstract class A implements I{
|
||||
use T;
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
public function foo($var) {
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Strict Standards: Declaration of B::foo() should be compatible with A::foo() in %sbug62358.php on line %d
|
21
Zend/tests/bug62892.phpt
Normal file
21
Zend/tests/bug62892.phpt
Normal file
@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
Bug #62892 (ReflectionClass::getTraitAliases crashes on importing trait methods as private)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
trait myTrait {
|
||||
public function run() {}
|
||||
}
|
||||
|
||||
class myClass {
|
||||
use myTrait {
|
||||
MyTrait::run as private;
|
||||
}
|
||||
}
|
||||
$class = new \ReflectionClass('myClass');
|
||||
var_dump($class->getTraitAliases());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(0) {
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Try catch finally
|
||||
Try catch finally (basic test)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo ($throw = FALSE) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Try catch finally return
|
||||
Try catch finally (basic test with return)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Try catch finally multi-return
|
||||
Try catch finally (with multi-returns)
|
||||
--FILE--
|
||||
<?php
|
||||
function dummy($msg) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Nesting try catch finally
|
||||
Try catch finally (nesting try-catch-finally)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Try catch finally with return
|
||||
Try catch finally (with multi-returns and exception)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo ($a) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Try catch finally: re-throw exception in catch block
|
||||
Try catch finally (re-throw exception in catch block)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo ($a) {
|
||||
|
52
Zend/tests/try_catch_finally_005.phpt
Normal file
52
Zend/tests/try_catch_finally_005.phpt
Normal file
@ -0,0 +1,52 @@
|
||||
--TEST--
|
||||
Try catch finally (break / cont in try block)
|
||||
--CREDITS--
|
||||
adoy
|
||||
--FILE--
|
||||
<?php
|
||||
for ($i = 0; $i < 100 ; $i ++) {
|
||||
try {
|
||||
break;
|
||||
} finally {
|
||||
var_dump("break");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for ($i = 0; $i < 2; $i ++) {
|
||||
try {
|
||||
continue;
|
||||
} finally {
|
||||
var_dump("continue1");
|
||||
}
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 3; $i ++) {
|
||||
try {
|
||||
try {
|
||||
continue;
|
||||
} finally {
|
||||
var_dump("continue2");
|
||||
if ($i == 1) {
|
||||
throw new Exception("continue exception");
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
var_dump("cactched");
|
||||
} finally {
|
||||
var_dump("finally");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(5) "break"
|
||||
string(9) "continue1"
|
||||
string(9) "continue1"
|
||||
string(9) "continue2"
|
||||
string(7) "finally"
|
||||
string(9) "continue2"
|
||||
string(8) "cactched"
|
||||
string(7) "finally"
|
||||
string(9) "continue2"
|
||||
string(7) "finally"
|
39
Zend/tests/try_catch_finally_006.phpt
Normal file
39
Zend/tests/try_catch_finally_006.phpt
Normal file
@ -0,0 +1,39 @@
|
||||
--TEST--
|
||||
Try catch finally (goto in try/catch block)
|
||||
--CREDITS--
|
||||
adoy
|
||||
--FILE--
|
||||
<?php
|
||||
function foo($ex = NULL) {
|
||||
try {
|
||||
try {
|
||||
goto label;
|
||||
} finally {
|
||||
var_dump("finally1");
|
||||
if ($ex) throw $ex;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
var_dump("catched");
|
||||
if ($ex) return "return1";
|
||||
} finally {
|
||||
var_dump("finally2");
|
||||
}
|
||||
|
||||
label:
|
||||
var_dump("label");
|
||||
return "return2";
|
||||
}
|
||||
|
||||
var_dump(foo());
|
||||
var_dump(foo(new Exception()));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(8) "finally1"
|
||||
string(8) "finally2"
|
||||
string(5) "label"
|
||||
string(7) "return2"
|
||||
string(8) "finally1"
|
||||
string(7) "catched"
|
||||
string(8) "finally2"
|
||||
string(7) "return1"
|
46
Zend/tests/try_catch_finally_007.phpt
Normal file
46
Zend/tests/try_catch_finally_007.phpt
Normal file
@ -0,0 +1,46 @@
|
||||
--TEST--
|
||||
Try catch finally (goto in try/catch block)
|
||||
--CREDITS--
|
||||
adoy
|
||||
--FILE--
|
||||
<?php
|
||||
function foo($ret = FALSE) {
|
||||
try {
|
||||
try {
|
||||
do {
|
||||
goto label;
|
||||
} while(0);
|
||||
foreach (array() as $val) {
|
||||
continue;
|
||||
}
|
||||
} finally {
|
||||
var_dump("finally1");
|
||||
throw new Exception("exception");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
goto local;
|
||||
local:
|
||||
var_dump("catched");
|
||||
if ($ret) return "return";
|
||||
} finally {
|
||||
var_dump("finally2");
|
||||
}
|
||||
|
||||
label:
|
||||
var_dump("label");
|
||||
}
|
||||
|
||||
var_dump(foo());
|
||||
var_dump(foo(true));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(8) "finally1"
|
||||
string(7) "catched"
|
||||
string(8) "finally2"
|
||||
string(5) "label"
|
||||
NULL
|
||||
string(8) "finally1"
|
||||
string(7) "catched"
|
||||
string(8) "finally2"
|
||||
string(6) "return"
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Try finally
|
||||
Try finally (basic test)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo ($a) {
|
||||
@ -20,4 +20,3 @@ Stack trace:
|
||||
#0 %stry_finally_001.php(%d): foo('finally')
|
||||
#1 {main}
|
||||
thrown in %stry_finally_001.php on line %d
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Try finally
|
||||
Try finally (re-throw exception in finally block)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Try finally
|
||||
Try finally (call sequence test)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Try without catch/finally block
|
||||
Try finally (without catch/finally block)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Finally with long goto
|
||||
Try finally (with long goto)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Finally with near goto
|
||||
Try finally (with near goto)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Finally with goto previous label
|
||||
Try finally (with goto previous label)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Finally with jmp (do while)
|
||||
Try finally (with break in do...while)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Finally with jmp (for continue)
|
||||
Try finally (with for continue)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo () {
|
||||
|
@ -22,7 +22,7 @@
|
||||
#ifndef ZEND_H
|
||||
#define ZEND_H
|
||||
|
||||
#define ZEND_VERSION "2.4.0"
|
||||
#define ZEND_VERSION "2.5.0-dev"
|
||||
|
||||
#define ZEND_ENGINE_2
|
||||
|
||||
|
@ -2531,6 +2531,9 @@ ZEND_API int zend_disable_function(char *function_name, uint function_name_lengt
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
#pragma optimize("", off)
|
||||
#endif
|
||||
static zend_object_value display_disabled_class(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_object_value retval;
|
||||
@ -2539,6 +2542,9 @@ static zend_object_value display_disabled_class(zend_class_entry *class_type TSR
|
||||
zend_error(E_WARNING, "%s() has been disabled for security reasons", class_type->name);
|
||||
return retval;
|
||||
}
|
||||
#ifdef ZEND_WIN32
|
||||
#pragma optimize("", on)
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
static const zend_function_entry disabled_class_new[] = {
|
||||
|
@ -2766,7 +2766,7 @@ void zend_initialize_try_catch_element(znode *catch_token TSRMLS_DC) /* {{{ */
|
||||
zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
|
||||
zend_llist_add_element(jmp_list_ptr, &jmp_op_number);
|
||||
|
||||
catch_token->EA = get_next_op_number(CG(active_op_array));
|
||||
catch_token->EA = get_next_op_number(CG(active_op_array));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -2862,6 +2862,7 @@ void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_to
|
||||
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_op = finally_token->u.op.opline_num;
|
||||
CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_end = get_next_op_number(CG(active_op_array));
|
||||
CG(active_op_array)->has_finally_block = 1;
|
||||
|
||||
opline->opcode = ZEND_LEAVE;
|
||||
SET_UNUSED(opline->op1);
|
||||
@ -3904,9 +3905,12 @@ static int zend_traits_merge_functions_to_class(zend_function *fn TSRMLS_DC, int
|
||||
if (prototype) {
|
||||
do_inheritance_check_on_method(fn, prototype TSRMLS_CC);
|
||||
}
|
||||
|
||||
/* one more thing: make sure we properly implement an abstract method */
|
||||
if (existing_fn && existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
|
||||
prototype = fn->common.prototype;
|
||||
do_inheritance_check_on_method(fn, existing_fn TSRMLS_CC);
|
||||
fn->common.prototype = prototype;
|
||||
}
|
||||
|
||||
/* delete inherited fn if the function to be added is not abstract */
|
||||
@ -3934,9 +3938,9 @@ static int zend_traits_merge_functions_to_class(zend_function *fn TSRMLS_DC, int
|
||||
if (zend_hash_quick_update(&ce->function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, &fn_copy, sizeof(zend_function), (void**)&fn_copy_p)==FAILURE) {
|
||||
zend_error(E_COMPILE_ERROR, "Trait method %s has not been applied, because failure occurred during updating class method table", hash_key->arKey);
|
||||
}
|
||||
|
||||
|
||||
zend_add_magic_methods(ce, hash_key->arKey, hash_key->nKeyLength, fn_copy_p TSRMLS_CC);
|
||||
|
||||
|
||||
zend_function_dtor(fn);
|
||||
} else {
|
||||
zend_function_dtor(fn);
|
||||
@ -4128,9 +4132,9 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /*
|
||||
|
||||
/** And, ensure that the referenced method is resolvable, too. */
|
||||
lcname = zend_str_tolower_dup(cur_method_ref->method_name,
|
||||
cur_method_ref->mname_len);
|
||||
cur_method_ref->mname_len);
|
||||
method_exists = zend_hash_exists(&cur_method_ref->ce->function_table,
|
||||
lcname, cur_method_ref->mname_len + 1);
|
||||
lcname, cur_method_ref->mname_len + 1);
|
||||
efree(lcname);
|
||||
|
||||
if (!method_exists) {
|
||||
@ -5112,11 +5116,11 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name
|
||||
opline->op2_type = IS_CONST;
|
||||
|
||||
if (doing_inheritance) {
|
||||
/* Make sure a trait does not try to extend a class */
|
||||
if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
|
||||
zend_error(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name);
|
||||
}
|
||||
|
||||
/* Make sure a trait does not try to extend a class */
|
||||
if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
|
||||
zend_error(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name);
|
||||
}
|
||||
|
||||
opline->extended_value = parent_class_name->u.op.var;
|
||||
opline->opcode = ZEND_DECLARE_INHERITED_CLASS;
|
||||
} else {
|
||||
@ -7065,9 +7069,9 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{
|
||||
lcname = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name));
|
||||
|
||||
if (((Z_STRLEN_P(name) == sizeof("self")-1) &&
|
||||
!memcmp(lcname, "self", sizeof("self")-1)) ||
|
||||
((Z_STRLEN_P(name) == sizeof("parent")-1) &&
|
||||
!memcmp(lcname, "parent", sizeof("parent")-1))) {
|
||||
!memcmp(lcname, "self", sizeof("self")-1)) ||
|
||||
((Z_STRLEN_P(name) == sizeof("parent")-1) &&
|
||||
!memcmp(lcname, "parent", sizeof("parent")-1))) {
|
||||
zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' is a special class name", Z_STRVAL_P(ns), Z_STRVAL_P(name), Z_STRVAL_P(name));
|
||||
}
|
||||
|
||||
|
@ -282,6 +282,7 @@ struct _zend_op_array {
|
||||
|
||||
zend_try_catch_element *try_catch_array;
|
||||
int last_try_catch;
|
||||
zend_bool has_finally_block;
|
||||
|
||||
/* static variables support */
|
||||
HashTable *static_variables;
|
||||
@ -384,7 +385,8 @@ struct _zend_execute_data {
|
||||
zend_class_entry *current_called_scope;
|
||||
zval *current_this;
|
||||
zval *current_object;
|
||||
zend_bool leaving;
|
||||
zend_uint leaving;
|
||||
zend_uint leaving_dest;
|
||||
};
|
||||
|
||||
#define EX(element) execute_data.element
|
||||
|
@ -87,6 +87,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
|
||||
|
||||
op_array->static_variables = NULL;
|
||||
op_array->last_try_catch = 0;
|
||||
op_array->has_finally_block = 0;
|
||||
|
||||
op_array->this_var = -1;
|
||||
|
||||
@ -551,8 +552,8 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
|
||||
}
|
||||
opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num];
|
||||
break;
|
||||
case ZEND_BRK:
|
||||
case ZEND_CONT:
|
||||
case ZEND_BRK:
|
||||
case ZEND_CONT:
|
||||
if (op_array->last_try_catch) {
|
||||
int nest_levels, array_offset;
|
||||
zend_brk_cont_element *jmp_to;
|
||||
|
@ -1840,6 +1840,390 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
|
||||
{
|
||||
zend_bool nested;
|
||||
zend_op_array *op_array = EX(op_array);
|
||||
|
||||
/* Generators go throw a different cleanup process */
|
||||
if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
|
||||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
/* Close the generator to free up resources */
|
||||
zend_generator_close(generator, 1 TSRMLS_CC);
|
||||
|
||||
/* Pass execution back to handling code */
|
||||
ZEND_VM_RETURN();
|
||||
}
|
||||
|
||||
EG(current_execute_data) = EX(prev_execute_data);
|
||||
EG(opline_ptr) = NULL;
|
||||
if (!EG(active_symbol_table)) {
|
||||
zend_free_compiled_variables(EX_CVs(), op_array->last_var);
|
||||
}
|
||||
|
||||
if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) {
|
||||
zval_ptr_dtor((zval**)&op_array->prototype);
|
||||
}
|
||||
|
||||
nested = EX(nested);
|
||||
|
||||
/* For generators the execute_data is stored on the heap, for everything
|
||||
* else it is stored on the VM stack. */
|
||||
if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
|
||||
efree(execute_data);
|
||||
} else {
|
||||
zend_vm_stack_free(execute_data TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (nested) {
|
||||
execute_data = EG(current_execute_data);
|
||||
}
|
||||
if (nested) {
|
||||
USE_OPLINE
|
||||
|
||||
LOAD_REGS();
|
||||
LOAD_OPLINE();
|
||||
if (UNEXPECTED(opline->opcode == ZEND_INCLUDE_OR_EVAL)) {
|
||||
|
||||
EX(function_state).function = (zend_function *) EX(op_array);
|
||||
EX(function_state).arguments = NULL;
|
||||
EX(object) = EX(current_object);
|
||||
|
||||
EG(opline_ptr) = &EX(opline);
|
||||
EG(active_op_array) = EX(op_array);
|
||||
EG(return_value_ptr_ptr) = EX(original_return_value);
|
||||
destroy_op_array(op_array TSRMLS_CC);
|
||||
efree(op_array);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL TSRMLS_CC);
|
||||
HANDLE_EXCEPTION_LEAVE();
|
||||
} else if (RETURN_VALUE_USED(opline)) {
|
||||
if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
|
||||
zval *retval;
|
||||
|
||||
ALLOC_ZVAL(retval);
|
||||
ZVAL_BOOL(retval, 1);
|
||||
INIT_PZVAL(retval);
|
||||
EX_T(opline->result.var).var.ptr = retval;
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_VM_INC_OPCODE();
|
||||
ZEND_VM_LEAVE();
|
||||
} else {
|
||||
EG(opline_ptr) = &EX(opline);
|
||||
EG(active_op_array) = EX(op_array);
|
||||
EG(return_value_ptr_ptr) = EX(original_return_value);
|
||||
if (EG(active_symbol_table)) {
|
||||
zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
|
||||
}
|
||||
EG(active_symbol_table) = EX(symbol_table);
|
||||
|
||||
EX(function_state).function = (zend_function *) EX(op_array);
|
||||
EX(function_state).arguments = NULL;
|
||||
|
||||
if (EG(This)) {
|
||||
if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
|
||||
if (IS_CTOR_USED(EX(called_scope))) {
|
||||
Z_DELREF_P(EG(This));
|
||||
}
|
||||
if (Z_REFCOUNT_P(EG(This)) == 1) {
|
||||
zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
zval_ptr_dtor(&EG(This));
|
||||
}
|
||||
EG(This) = EX(current_this);
|
||||
EG(scope) = EX(current_scope);
|
||||
EG(called_scope) = EX(current_called_scope);
|
||||
|
||||
EX(object) = EX(current_object);
|
||||
EX(called_scope) = DECODE_CTOR(EX(called_scope));
|
||||
|
||||
zend_vm_stack_clear_multiple(TSRMLS_C);
|
||||
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL TSRMLS_CC);
|
||||
if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
|
||||
}
|
||||
HANDLE_EXCEPTION_LEAVE();
|
||||
}
|
||||
|
||||
ZEND_VM_INC_OPCODE();
|
||||
ZEND_VM_LEAVE();
|
||||
}
|
||||
}
|
||||
ZEND_VM_RETURN();
|
||||
}
|
||||
|
||||
ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_bool should_change_scope = 0;
|
||||
zend_function *fbc = EX(function_state).function;
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name, fbc->common.function_name);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE(); /* Never reached */
|
||||
}
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
|
||||
fbc->common.scope ? fbc->common.scope->name : "",
|
||||
fbc->common.scope ? "::" : "",
|
||||
fbc->common.function_name);
|
||||
}
|
||||
}
|
||||
if (fbc->common.scope &&
|
||||
!(fbc->common.fn_flags & ZEND_ACC_STATIC) &&
|
||||
!EX(object)) {
|
||||
|
||||
if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
|
||||
/* FIXME: output identifiers properly */
|
||||
zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name, fbc->common.function_name);
|
||||
} else {
|
||||
/* FIXME: output identifiers properly */
|
||||
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
|
||||
zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically", fbc->common.scope->name, fbc->common.function_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (fbc->type == ZEND_USER_FUNCTION || fbc->common.scope) {
|
||||
should_change_scope = 1;
|
||||
EX(current_this) = EG(This);
|
||||
EX(current_scope) = EG(scope);
|
||||
EX(current_called_scope) = EG(called_scope);
|
||||
EG(This) = EX(object);
|
||||
EG(scope) = (fbc->type == ZEND_USER_FUNCTION || !EX(object)) ? fbc->common.scope : NULL;
|
||||
EG(called_scope) = EX(called_scope);
|
||||
}
|
||||
|
||||
zend_arg_types_stack_3_pop(&EG(arg_types_stack), &EX(called_scope), &EX(current_object), &EX(fbc));
|
||||
EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
|
||||
LOAD_OPLINE();
|
||||
|
||||
if (fbc->type == ZEND_INTERNAL_FUNCTION) {
|
||||
temp_variable *ret = &EX_T(opline->result.var);
|
||||
|
||||
MAKE_STD_ZVAL(ret->var.ptr);
|
||||
ZVAL_NULL(ret->var.ptr);
|
||||
ret->var.ptr_ptr = &ret->var.ptr;
|
||||
ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
|
||||
|
||||
if (fbc->common.arg_info) {
|
||||
zend_uint i=0;
|
||||
zval **p = (zval**)EX(function_state).arguments;
|
||||
ulong arg_count = opline->extended_value;
|
||||
|
||||
while (arg_count>0) {
|
||||
zend_verify_arg_type(fbc, ++i, *(p-arg_count), 0 TSRMLS_CC);
|
||||
arg_count--;
|
||||
}
|
||||
}
|
||||
|
||||
if (!zend_execute_internal) {
|
||||
/* saves one function call if zend_execute_internal is not used */
|
||||
fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
} else {
|
||||
zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(&ret->var.ptr);
|
||||
}
|
||||
} else if (fbc->type == ZEND_USER_FUNCTION) {
|
||||
EX(original_return_value) = EG(return_value_ptr_ptr);
|
||||
EG(active_symbol_table) = NULL;
|
||||
EG(active_op_array) = &fbc->op_array;
|
||||
EG(return_value_ptr_ptr) = NULL;
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
temp_variable *ret = &EX_T(opline->result.var);
|
||||
|
||||
ret->var.ptr = NULL;
|
||||
EG(return_value_ptr_ptr) = &ret->var.ptr;
|
||||
ret->var.ptr_ptr = &ret->var.ptr;
|
||||
ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
|
||||
}
|
||||
|
||||
if (EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) {
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
EX_T(opline->result.var).var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
|
||||
}
|
||||
} else if (EXPECTED(zend_execute == execute)) {
|
||||
if (EXPECTED(EG(exception) == NULL)) {
|
||||
ZEND_VM_ENTER();
|
||||
}
|
||||
} else {
|
||||
zend_execute(EG(active_op_array) TSRMLS_CC);
|
||||
}
|
||||
|
||||
EG(opline_ptr) = &EX(opline);
|
||||
EG(active_op_array) = EX(op_array);
|
||||
EG(return_value_ptr_ptr) = EX(original_return_value);
|
||||
if (EG(active_symbol_table)) {
|
||||
zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
|
||||
}
|
||||
EG(active_symbol_table) = EX(symbol_table);
|
||||
} else { /* ZEND_OVERLOADED_FUNCTION */
|
||||
MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr);
|
||||
ZVAL_NULL(EX_T(opline->result.var).var.ptr);
|
||||
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
if (EXPECTED(EX(object) != NULL)) {
|
||||
Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
|
||||
}
|
||||
|
||||
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
|
||||
efree((char*)fbc->common.function_name);
|
||||
}
|
||||
efree(fbc);
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
|
||||
} else {
|
||||
Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr);
|
||||
Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, 1);
|
||||
EX_T(opline->result.var).var.fcall_returned_reference = 0;
|
||||
EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
|
||||
}
|
||||
}
|
||||
|
||||
EX(function_state).function = (zend_function *) EX(op_array);
|
||||
EX(function_state).arguments = NULL;
|
||||
|
||||
if (should_change_scope) {
|
||||
if (EG(This)) {
|
||||
if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
|
||||
if (IS_CTOR_USED(EX(called_scope))) {
|
||||
Z_DELREF_P(EG(This));
|
||||
}
|
||||
if (Z_REFCOUNT_P(EG(This)) == 1) {
|
||||
zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
zval_ptr_dtor(&EG(This));
|
||||
}
|
||||
EG(This) = EX(current_this);
|
||||
EG(scope) = EX(current_scope);
|
||||
EG(called_scope) = EX(current_called_scope);
|
||||
}
|
||||
|
||||
EX(object) = EX(current_object);
|
||||
EX(called_scope) = DECODE_CTOR(EX(called_scope));
|
||||
|
||||
zend_vm_stack_clear_multiple(TSRMLS_C);
|
||||
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL TSRMLS_CC);
|
||||
if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
|
||||
}
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HELPER_EX(zend_finally_handler_leaving, ANY, ANY, int type)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
|
||||
SAVE_OPLINE();
|
||||
|
||||
switch (type) {
|
||||
case ZEND_THROW:
|
||||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
case ZEND_LEAVE:
|
||||
{
|
||||
if (EG(prev_exception) || (type == ZEND_LEAVE && EG(exception))) {
|
||||
for (i=0; i<EX(op_array)->last_try_catch; i++) {
|
||||
if (EX(op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EX(op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EX(op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (op_num < EX(op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<EX(op_array)->last_try_catch; i++) {
|
||||
if (EX(op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EX(op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EX(op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
/* EG(exception) || EG(prev_exception) */
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = ZEND_THROW;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
} else if (finally_op_num) {
|
||||
if (type != ZEND_LEAVE) {
|
||||
EX(leaving) = type;
|
||||
}
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
} else if (EX(leaving) && type != ZEND_LEAVE) {
|
||||
/* leave it to ZEND_LEAVE */
|
||||
EX(leaving) = type;
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_JMP:
|
||||
case ZEND_BRK:
|
||||
case ZEND_CONT:
|
||||
case ZEND_GOTO:
|
||||
{
|
||||
/* these can not occurred in exception context */
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op
|
||||
&& (EX(leaving_dest) < EG(active_op_array)->try_catch_array[i].try_op
|
||||
|| EX(leaving_dest) >= EG(active_op_array)->try_catch_array[i].finally_end)) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
}
|
||||
|
||||
if (finally_op_num) {
|
||||
EX(leaving) = type;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[EX(leaving_dest)]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -1847,6 +2231,10 @@ ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY)
|
||||
#if DEBUG_ZEND>=2
|
||||
printf("Jumping to %d\n", opline->op1.opline_num);
|
||||
#endif
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
EX(leaving_dest) = opline->op1.jmp_addr - EX(op_array)->opcodes;
|
||||
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type, ZEND_JMP);
|
||||
}
|
||||
ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
|
||||
ZEND_VM_CONTINUE(); /* CHECK_ME */
|
||||
}
|
||||
@ -2508,298 +2896,6 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
|
||||
{
|
||||
zend_bool nested;
|
||||
zend_op_array *op_array = EX(op_array);
|
||||
|
||||
/* Generators go throw a different cleanup process */
|
||||
if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
|
||||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
/* Close the generator to free up resources */
|
||||
zend_generator_close(generator, 1 TSRMLS_CC);
|
||||
|
||||
/* Pass execution back to handling code */
|
||||
ZEND_VM_RETURN();
|
||||
}
|
||||
|
||||
EG(current_execute_data) = EX(prev_execute_data);
|
||||
EG(opline_ptr) = NULL;
|
||||
if (!EG(active_symbol_table)) {
|
||||
zend_free_compiled_variables(EX_CVs(), op_array->last_var);
|
||||
}
|
||||
|
||||
if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) {
|
||||
zval_ptr_dtor((zval**)&op_array->prototype);
|
||||
}
|
||||
|
||||
nested = EX(nested);
|
||||
|
||||
/* For generators the execute_data is stored on the heap, for everything
|
||||
* else it is stored on the VM stack. */
|
||||
if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
|
||||
efree(execute_data);
|
||||
} else {
|
||||
zend_vm_stack_free(execute_data TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (nested) {
|
||||
execute_data = EG(current_execute_data);
|
||||
}
|
||||
if (nested) {
|
||||
USE_OPLINE
|
||||
|
||||
LOAD_REGS();
|
||||
LOAD_OPLINE();
|
||||
if (UNEXPECTED(opline->opcode == ZEND_INCLUDE_OR_EVAL)) {
|
||||
|
||||
EX(function_state).function = (zend_function *) EX(op_array);
|
||||
EX(function_state).arguments = NULL;
|
||||
EX(object) = EX(current_object);
|
||||
|
||||
EG(opline_ptr) = &EX(opline);
|
||||
EG(active_op_array) = EX(op_array);
|
||||
EG(return_value_ptr_ptr) = EX(original_return_value);
|
||||
destroy_op_array(op_array TSRMLS_CC);
|
||||
efree(op_array);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL TSRMLS_CC);
|
||||
HANDLE_EXCEPTION_LEAVE();
|
||||
} else if (RETURN_VALUE_USED(opline)) {
|
||||
if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
|
||||
zval *retval;
|
||||
|
||||
ALLOC_ZVAL(retval);
|
||||
ZVAL_BOOL(retval, 1);
|
||||
INIT_PZVAL(retval);
|
||||
EX_T(opline->result.var).var.ptr = retval;
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_VM_INC_OPCODE();
|
||||
ZEND_VM_LEAVE();
|
||||
} else {
|
||||
|
||||
EG(opline_ptr) = &EX(opline);
|
||||
EG(active_op_array) = EX(op_array);
|
||||
EG(return_value_ptr_ptr) = EX(original_return_value);
|
||||
if (EG(active_symbol_table)) {
|
||||
zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
|
||||
}
|
||||
EG(active_symbol_table) = EX(symbol_table);
|
||||
|
||||
EX(function_state).function = (zend_function *) EX(op_array);
|
||||
EX(function_state).arguments = NULL;
|
||||
|
||||
if (EG(This)) {
|
||||
if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
|
||||
if (IS_CTOR_USED(EX(called_scope))) {
|
||||
Z_DELREF_P(EG(This));
|
||||
}
|
||||
if (Z_REFCOUNT_P(EG(This)) == 1) {
|
||||
zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
zval_ptr_dtor(&EG(This));
|
||||
}
|
||||
EG(This) = EX(current_this);
|
||||
EG(scope) = EX(current_scope);
|
||||
EG(called_scope) = EX(current_called_scope);
|
||||
|
||||
EX(object) = EX(current_object);
|
||||
EX(called_scope) = DECODE_CTOR(EX(called_scope));
|
||||
|
||||
zend_vm_stack_clear_multiple(TSRMLS_C);
|
||||
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL TSRMLS_CC);
|
||||
if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
|
||||
}
|
||||
HANDLE_EXCEPTION_LEAVE();
|
||||
}
|
||||
|
||||
ZEND_VM_INC_OPCODE();
|
||||
ZEND_VM_LEAVE();
|
||||
}
|
||||
}
|
||||
ZEND_VM_RETURN();
|
||||
}
|
||||
|
||||
ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_bool should_change_scope = 0;
|
||||
zend_function *fbc = EX(function_state).function;
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name, fbc->common.function_name);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE(); /* Never reached */
|
||||
}
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
|
||||
fbc->common.scope ? fbc->common.scope->name : "",
|
||||
fbc->common.scope ? "::" : "",
|
||||
fbc->common.function_name);
|
||||
}
|
||||
}
|
||||
if (fbc->common.scope &&
|
||||
!(fbc->common.fn_flags & ZEND_ACC_STATIC) &&
|
||||
!EX(object)) {
|
||||
|
||||
if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
|
||||
/* FIXME: output identifiers properly */
|
||||
zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name, fbc->common.function_name);
|
||||
} else {
|
||||
/* FIXME: output identifiers properly */
|
||||
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
|
||||
zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically", fbc->common.scope->name, fbc->common.function_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (fbc->type == ZEND_USER_FUNCTION || fbc->common.scope) {
|
||||
should_change_scope = 1;
|
||||
EX(current_this) = EG(This);
|
||||
EX(current_scope) = EG(scope);
|
||||
EX(current_called_scope) = EG(called_scope);
|
||||
EG(This) = EX(object);
|
||||
EG(scope) = (fbc->type == ZEND_USER_FUNCTION || !EX(object)) ? fbc->common.scope : NULL;
|
||||
EG(called_scope) = EX(called_scope);
|
||||
}
|
||||
|
||||
zend_arg_types_stack_3_pop(&EG(arg_types_stack), &EX(called_scope), &EX(current_object), &EX(fbc));
|
||||
EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
|
||||
LOAD_OPLINE();
|
||||
|
||||
if (fbc->type == ZEND_INTERNAL_FUNCTION) {
|
||||
temp_variable *ret = &EX_T(opline->result.var);
|
||||
|
||||
MAKE_STD_ZVAL(ret->var.ptr);
|
||||
ZVAL_NULL(ret->var.ptr);
|
||||
ret->var.ptr_ptr = &ret->var.ptr;
|
||||
ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
|
||||
|
||||
if (fbc->common.arg_info) {
|
||||
zend_uint i=0;
|
||||
zval **p = (zval**)EX(function_state).arguments;
|
||||
ulong arg_count = opline->extended_value;
|
||||
|
||||
while (arg_count>0) {
|
||||
zend_verify_arg_type(fbc, ++i, *(p-arg_count), 0 TSRMLS_CC);
|
||||
arg_count--;
|
||||
}
|
||||
}
|
||||
|
||||
if (!zend_execute_internal) {
|
||||
/* saves one function call if zend_execute_internal is not used */
|
||||
fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
} else {
|
||||
zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(&ret->var.ptr);
|
||||
}
|
||||
} else if (fbc->type == ZEND_USER_FUNCTION) {
|
||||
EX(original_return_value) = EG(return_value_ptr_ptr);
|
||||
EG(active_symbol_table) = NULL;
|
||||
EG(active_op_array) = &fbc->op_array;
|
||||
EG(return_value_ptr_ptr) = NULL;
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
temp_variable *ret = &EX_T(opline->result.var);
|
||||
|
||||
ret->var.ptr = NULL;
|
||||
EG(return_value_ptr_ptr) = &ret->var.ptr;
|
||||
ret->var.ptr_ptr = &ret->var.ptr;
|
||||
ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
|
||||
}
|
||||
|
||||
if (EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) {
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
EX_T(opline->result.var).var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
|
||||
}
|
||||
} else if (EXPECTED(zend_execute == execute)) {
|
||||
if (EXPECTED(EG(exception) == NULL)) {
|
||||
ZEND_VM_ENTER();
|
||||
}
|
||||
} else {
|
||||
zend_execute(EG(active_op_array) TSRMLS_CC);
|
||||
}
|
||||
|
||||
EG(opline_ptr) = &EX(opline);
|
||||
EG(active_op_array) = EX(op_array);
|
||||
EG(return_value_ptr_ptr) = EX(original_return_value);
|
||||
if (EG(active_symbol_table)) {
|
||||
zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
|
||||
}
|
||||
EG(active_symbol_table) = EX(symbol_table);
|
||||
} else { /* ZEND_OVERLOADED_FUNCTION */
|
||||
MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr);
|
||||
ZVAL_NULL(EX_T(opline->result.var).var.ptr);
|
||||
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
if (EXPECTED(EX(object) != NULL)) {
|
||||
Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
|
||||
}
|
||||
|
||||
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
|
||||
efree((char*)fbc->common.function_name);
|
||||
}
|
||||
efree(fbc);
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
|
||||
} else {
|
||||
Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr);
|
||||
Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, 1);
|
||||
EX_T(opline->result.var).var.fcall_returned_reference = 0;
|
||||
EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
|
||||
}
|
||||
}
|
||||
|
||||
EX(function_state).function = (zend_function *) EX(op_array);
|
||||
EX(function_state).arguments = NULL;
|
||||
|
||||
if (should_change_scope) {
|
||||
if (EG(This)) {
|
||||
if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
|
||||
if (IS_CTOR_USED(EX(called_scope))) {
|
||||
Z_DELREF_P(EG(This));
|
||||
}
|
||||
if (Z_REFCOUNT_P(EG(This)) == 1) {
|
||||
zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
zval_ptr_dtor(&EG(This));
|
||||
}
|
||||
EG(This) = EX(current_this);
|
||||
EG(scope) = EX(current_scope);
|
||||
EG(called_scope) = EX(current_called_scope);
|
||||
}
|
||||
|
||||
EX(object) = EX(current_object);
|
||||
EX(called_scope) = DECODE_CTOR(EX(called_scope));
|
||||
|
||||
zend_vm_stack_clear_multiple(TSRMLS_C);
|
||||
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL TSRMLS_CC);
|
||||
if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
|
||||
}
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(61, ZEND_DO_FCALL_BY_NAME, ANY, ANY)
|
||||
{
|
||||
EX(function_state).function = EX(fbc);
|
||||
@ -2888,49 +2984,10 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
|
||||
}
|
||||
FREE_OP1_IF_VAR();
|
||||
|
||||
if (!(EG(active_op_array)->last_try_catch)) {
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||
} else {
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(prev_exception)) {
|
||||
/* leaving */
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type, ZEND_RETURN);
|
||||
}
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
|
||||
@ -3003,49 +3060,10 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
|
||||
|
||||
FREE_OP1_IF_VAR();
|
||||
|
||||
if (!(EG(active_op_array)->last_try_catch)) {
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||
} else {
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(prev_exception)) {
|
||||
/* leaving */
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type, ZEND_RETURN_BY_REF);
|
||||
}
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
|
||||
@ -3389,6 +3407,10 @@ ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST)
|
||||
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
|
||||
EX(op_array), EX_Ts() TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
EX(leaving_dest) = el->brk;
|
||||
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type, ZEND_BRK);
|
||||
}
|
||||
ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
|
||||
}
|
||||
|
||||
@ -3401,6 +3423,10 @@ ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST)
|
||||
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
|
||||
EX(op_array), EX_Ts() TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (EG(active_op_array)->has_finally_block) {
|
||||
EX(leaving_dest) = el->cont;
|
||||
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type, ZEND_CONT);
|
||||
}
|
||||
ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
|
||||
}
|
||||
|
||||
@ -3428,6 +3454,10 @@ ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
EX(leaving_dest) = opline->op1.jmp_addr - EX(op_array)->opcodes;
|
||||
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type, ZEND_GOTO);
|
||||
}
|
||||
ZEND_VM_JMP(opline->op1.jmp_addr);
|
||||
}
|
||||
|
||||
@ -5211,7 +5241,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
zend_exception_save(TSRMLS_C);
|
||||
EX(leaving) = finally;
|
||||
EX(leaving) = ZEND_THROW;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
@ -5221,7 +5251,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally) {
|
||||
zend_exception_save(TSRMLS_C);
|
||||
EX(leaving) = finally;
|
||||
EX(leaving) = ZEND_THROW;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
@ -5346,48 +5376,26 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
|
||||
|
||||
ZEND_VM_HANDLER(159, ZEND_LEAVE, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_uint i, op_num = opline - EG(active_op_array)->opcodes;
|
||||
|
||||
SAVE_OPLINE();
|
||||
zend_exception_restore(TSRMLS_C);
|
||||
if (EX(leaving)) {
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i = 0; i < EX(leaving); i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(exception)) {
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||
}
|
||||
} else {
|
||||
if (!EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
zend_uint leaving = EX(leaving);
|
||||
switch (leaving) {
|
||||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
case ZEND_THROW:
|
||||
leaving = ZEND_LEAVE;
|
||||
case ZEND_JMP:
|
||||
case ZEND_BRK:
|
||||
case ZEND_CONT:
|
||||
case ZEND_GOTO:
|
||||
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type, leaving);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSED)
|
||||
|
@ -464,33 +464,6 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
|
||||
execute_ex(execute_data TSRMLS_CC);
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
||||
#if DEBUG_ZEND>=2
|
||||
printf("Jumping to %d\n", opline->op1.opline_num);
|
||||
#endif
|
||||
ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
|
||||
ZEND_VM_CONTINUE(); /* CHECK_ME */
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *tmp = &EX_T(opline->result.var).tmp_var;
|
||||
|
||||
SAVE_OPLINE();
|
||||
tmp->value.str.val = emalloc(1);
|
||||
tmp->value.str.val[0] = 0;
|
||||
tmp->value.str.len = 0;
|
||||
Z_SET_REFCOUNT_P(tmp, 1);
|
||||
tmp->type = IS_STRING;
|
||||
Z_UNSET_ISREF_P(tmp);
|
||||
/*CHECK_EXCEPTION();*/
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_bool nested;
|
||||
@ -564,7 +537,6 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
|
||||
ZEND_VM_INC_OPCODE();
|
||||
ZEND_VM_LEAVE();
|
||||
} else {
|
||||
|
||||
EG(opline_ptr) = &EX(opline);
|
||||
EG(active_op_array) = EX(op_array);
|
||||
EG(return_value_ptr_ptr) = EX(original_return_value);
|
||||
@ -725,7 +697,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
|
||||
MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr);
|
||||
ZVAL_NULL(EX_T(opline->result.var).var.ptr);
|
||||
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
if (EXPECTED(EX(object) != NULL)) {
|
||||
Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
} else {
|
||||
@ -783,6 +755,130 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL zend_finally_handler_leaving_SPEC(int type, ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
|
||||
SAVE_OPLINE();
|
||||
|
||||
switch (type) {
|
||||
case ZEND_THROW:
|
||||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
case ZEND_LEAVE:
|
||||
{
|
||||
if (EG(prev_exception) || (type == ZEND_LEAVE && EG(exception))) {
|
||||
for (i=0; i<EX(op_array)->last_try_catch; i++) {
|
||||
if (EX(op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EX(op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EX(op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (op_num < EX(op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<EX(op_array)->last_try_catch; i++) {
|
||||
if (EX(op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EX(op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EX(op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
/* EG(exception) || EG(prev_exception) */
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = ZEND_THROW;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
} else if (finally_op_num) {
|
||||
if (type != ZEND_LEAVE) {
|
||||
EX(leaving) = type;
|
||||
}
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
} else if (EX(leaving) && type != ZEND_LEAVE) {
|
||||
/* leave it to ZEND_LEAVE */
|
||||
EX(leaving) = type;
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_JMP:
|
||||
case ZEND_BRK:
|
||||
case ZEND_CONT:
|
||||
case ZEND_GOTO:
|
||||
{
|
||||
/* these can not occurred in exception context */
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op
|
||||
&& (EX(leaving_dest) < EG(active_op_array)->try_catch_array[i].try_op
|
||||
|| EX(leaving_dest) >= EG(active_op_array)->try_catch_array[i].finally_end)) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
}
|
||||
|
||||
if (finally_op_num) {
|
||||
EX(leaving) = type;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[EX(leaving_dest)]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
||||
#if DEBUG_ZEND>=2
|
||||
printf("Jumping to %d\n", opline->op1.opline_num);
|
||||
#endif
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
EX(leaving_dest) = opline->op1.jmp_addr - EX(op_array)->opcodes;
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_JMP, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
|
||||
ZEND_VM_CONTINUE(); /* CHECK_ME */
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *tmp = &EX_T(opline->result.var).tmp_var;
|
||||
|
||||
SAVE_OPLINE();
|
||||
tmp->value.str.val = emalloc(1);
|
||||
tmp->value.str.val[0] = 0;
|
||||
tmp->value.str.len = 0;
|
||||
Z_SET_REFCOUNT_P(tmp, 1);
|
||||
tmp->type = IS_STRING;
|
||||
Z_UNSET_ISREF_P(tmp);
|
||||
/*CHECK_EXCEPTION();*/
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
EX(function_state).function = EX(fbc);
|
||||
@ -1175,7 +1271,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
zend_exception_save(TSRMLS_C);
|
||||
EX(leaving) = finally;
|
||||
EX(leaving) = ZEND_THROW;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
@ -1185,7 +1281,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally) {
|
||||
zend_exception_save(TSRMLS_C);
|
||||
EX(leaving) = finally;
|
||||
EX(leaving) = ZEND_THROW;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
@ -1230,48 +1326,26 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS
|
||||
|
||||
static int ZEND_FASTCALL ZEND_LEAVE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_uint i, op_num = opline - EG(active_op_array)->opcodes;
|
||||
|
||||
SAVE_OPLINE();
|
||||
zend_exception_restore(TSRMLS_C);
|
||||
if (EX(leaving)) {
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i = 0; i < EX(leaving); i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(exception)) {
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
} else {
|
||||
if (!EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
zend_uint leaving = EX(leaving);
|
||||
switch (leaving) {
|
||||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
case ZEND_THROW:
|
||||
leaving = ZEND_LEAVE;
|
||||
case ZEND_JMP:
|
||||
case ZEND_BRK:
|
||||
case ZEND_CONT:
|
||||
case ZEND_GOTO:
|
||||
return zend_finally_handler_leaving_SPEC(leaving, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@ -1508,6 +1582,10 @@ static int ZEND_FASTCALL ZEND_BRK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
|
||||
EX(op_array), EX_Ts() TSRMLS_CC);
|
||||
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
EX(leaving_dest) = el->brk;
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_BRK, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
|
||||
}
|
||||
|
||||
@ -1520,6 +1598,10 @@ static int ZEND_FASTCALL ZEND_CONT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
|
||||
EX(op_array), EX_Ts() TSRMLS_CC);
|
||||
|
||||
if (EG(active_op_array)->has_finally_block) {
|
||||
EX(leaving_dest) = el->cont;
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_CONT, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
|
||||
}
|
||||
|
||||
@ -1547,6 +1629,10 @@ static int ZEND_FASTCALL ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
EX(leaving_dest) = opline->op1.jmp_addr - EX(op_array)->opcodes;
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_GOTO, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
ZEND_VM_JMP(opline->op1.jmp_addr);
|
||||
}
|
||||
|
||||
@ -2409,49 +2495,10 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
||||
*EG(return_value_ptr_ptr) = ret;
|
||||
}
|
||||
|
||||
if (!(EG(active_op_array)->last_try_catch)) {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else {
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(prev_exception)) {
|
||||
/* leaving */
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_RETURN, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@ -2522,49 +2569,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (!(EG(active_op_array)->last_try_catch)) {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else {
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(prev_exception)) {
|
||||
/* leaving */
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_RETURN_BY_REF, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@ -7804,49 +7812,10 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
*EG(return_value_ptr_ptr) = ret;
|
||||
}
|
||||
|
||||
if (!(EG(active_op_array)->last_try_catch)) {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else {
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(prev_exception)) {
|
||||
/* leaving */
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_RETURN, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@ -7917,49 +7886,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (!(EG(active_op_array)->last_try_catch)) {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else {
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(prev_exception)) {
|
||||
/* leaving */
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_RETURN_BY_REF, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@ -13105,49 +13035,10 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
}
|
||||
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
|
||||
|
||||
if (!(EG(active_op_array)->last_try_catch)) {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else {
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(prev_exception)) {
|
||||
/* leaving */
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_RETURN, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@ -13220,49 +13111,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
|
||||
|
||||
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
|
||||
|
||||
if (!(EG(active_op_array)->last_try_catch)) {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else {
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(prev_exception)) {
|
||||
/* leaving */
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_RETURN_BY_REF, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@ -30730,49 +30582,10 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
*EG(return_value_ptr_ptr) = ret;
|
||||
}
|
||||
|
||||
if (!(EG(active_op_array)->last_try_catch)) {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else {
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(prev_exception)) {
|
||||
/* leaving */
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_RETURN, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@ -30843,49 +30656,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (!(EG(active_op_array)->last_try_catch)) {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else {
|
||||
zend_uint i, op_num = opline - EX(op_array)->opcodes;
|
||||
zend_uint catch_op_num = 0, finally_op_num = 0;
|
||||
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
|
||||
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
|
||||
break;
|
||||
}
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
|
||||
finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
|
||||
}
|
||||
if (EG(prev_exception)) {
|
||||
/* leaving */
|
||||
if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (catch_op_num && finally_op_num) {
|
||||
if (catch_op_num > finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else {
|
||||
EX(leaving) = 0;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
} else if (catch_op_num) {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (finally_op_num) {
|
||||
EX(leaving) = 1;
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EX(leaving)) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
if (EX(op_array)->has_finally_block) {
|
||||
return zend_finally_handler_leaving_SPEC(ZEND_RETURN_BY_REF, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
|
@ -1,90 +0,0 @@
|
||||
--TEST--
|
||||
gmp_gcdext() basic tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("gmp")) print "skip";
|
||||
if(substr(PHP_OS, 0, 3) != 'WIN' ) {
|
||||
die('skip windows only test');
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$n = gmp_init("34293864345");
|
||||
$n1 = gmp_init("23434293864345");
|
||||
|
||||
$a = array(
|
||||
array(123,45),
|
||||
array(4341,9734),
|
||||
array(23487,333),
|
||||
array(-234234,-123123),
|
||||
array(-100,-2234),
|
||||
array(345,"34587345"),
|
||||
array(345,"0"),
|
||||
array("345556456",345873),
|
||||
array("34545345556456","323432445873"),
|
||||
array($n, $n1),
|
||||
);
|
||||
|
||||
foreach ($a as $val) {
|
||||
$r = gmp_gcdext($val[0],$val[1]);
|
||||
var_dump(gmp_strval($r['g']));
|
||||
var_dump(gmp_strval($r['s']));
|
||||
var_dump(gmp_strval($r['t']));
|
||||
}
|
||||
|
||||
var_dump(gmp_gcdext($val[0],array()));
|
||||
var_dump(gmp_gcdext(array(),array()));
|
||||
var_dump(gmp_gcdext(array(),array(),1));
|
||||
var_dump(gmp_gcdext(array()));
|
||||
var_dump(gmp_gcdext());
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(1) "3"
|
||||
string(2) "41"
|
||||
string(4) "-112"
|
||||
string(1) "1"
|
||||
string(4) "-805"
|
||||
string(3) "359"
|
||||
string(1) "3"
|
||||
string(2) "32"
|
||||
string(5) "-2257"
|
||||
string(4) "3003"
|
||||
string(3) "-10"
|
||||
string(2) "19"
|
||||
string(1) "2"
|
||||
string(2) "67"
|
||||
string(2) "-3"
|
||||
string(2) "15"
|
||||
string(7) "-601519"
|
||||
string(1) "6"
|
||||
string(3) "345"
|
||||
string(1) "1"
|
||||
string(1) "0"
|
||||
string(1) "1"
|
||||
string(5) "84319"
|
||||
string(9) "-84241831"
|
||||
string(1) "1"
|
||||
string(12) "167180205823"
|
||||
string(15) "-17856272782919"
|
||||
string(3) "195"
|
||||
string(15) "-23387298979862"
|
||||
string(11) "34225091793"
|
||||
|
||||
Warning: gmp_gcdext(): Unable to convert variable to GMP - wrong type in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: gmp_gcdext(): Unable to convert variable to GMP - wrong type in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: gmp_gcdext() expects exactly 2 parameters, 3 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: gmp_gcdext() expects exactly 2 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: gmp_gcdext() expects exactly 2 parameters, 0 given in %s on line %d
|
||||
NULL
|
||||
Done
|
||||
|
@ -2,9 +2,6 @@
|
||||
gmp_gcdext() basic tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("gmp")) print "skip";
|
||||
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||
die('skip.. only for Non Windows Systems');
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
@ -1,45 +0,0 @@
|
||||
--TEST--
|
||||
gmp_nextprime()
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("gmp")) print "skip";
|
||||
if(substr(PHP_OS, 0, 3) != 'WIN' ) {
|
||||
die('skip windows only test');
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$n = gmp_nextprime(-1);
|
||||
var_dump(gmp_strval($n));
|
||||
$n = gmp_nextprime(0);
|
||||
var_dump(gmp_strval($n));
|
||||
$n = gmp_nextprime(-1000);
|
||||
var_dump(gmp_strval($n));
|
||||
$n = gmp_nextprime(1000);
|
||||
var_dump(gmp_strval($n));
|
||||
$n = gmp_nextprime(100000);
|
||||
var_dump(gmp_strval($n));
|
||||
$n = gmp_nextprime(array());
|
||||
var_dump(gmp_strval($n));
|
||||
$n = gmp_nextprime("");
|
||||
var_dump(gmp_strval($n));
|
||||
$n = gmp_nextprime(new stdclass());
|
||||
var_dump(gmp_strval($n));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(1) "2"
|
||||
string(1) "2"
|
||||
string(4) "-997"
|
||||
string(4) "1009"
|
||||
string(6) "100003"
|
||||
|
||||
Warning: gmp_nextprime(): Unable to convert variable to GMP - wrong type in %s on line %d
|
||||
string(1) "0"
|
||||
string(1) "0"
|
||||
|
||||
Warning: gmp_nextprime(): Unable to convert variable to GMP - wrong type in %s on line %d
|
||||
string(1) "0"
|
||||
Done
|
||||
|
@ -2,9 +2,6 @@
|
||||
gmp_nextprime()
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("gmp")) print "skip";
|
||||
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||
die('skip.. only for Non Windows Systems');
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
@ -20,8 +20,9 @@
|
||||
|
||||
#include <php.h>
|
||||
|
||||
#include "intl_common.h"
|
||||
#include "intl_error.h"
|
||||
#include "../intl_common.h"
|
||||
#include "../intl_error.h"
|
||||
#include "../intl_data.h"
|
||||
|
||||
#include <unicode/ucol.h>
|
||||
|
||||
@ -54,9 +55,7 @@ extern zend_class_entry *Collator_ce_ptr;
|
||||
Collator_object* co = NULL; \
|
||||
intl_error_reset( NULL TSRMLS_CC ); \
|
||||
|
||||
#define COLLATOR_METHOD_FETCH_OBJECT \
|
||||
co = (Collator_object *) zend_object_store_get_object( object TSRMLS_CC ); \
|
||||
intl_error_reset( COLLATOR_ERROR_P( co ) TSRMLS_CC ); \
|
||||
#define COLLATOR_METHOD_FETCH_OBJECT INTL_METHOD_FETCH_OBJECT(Collator, co)
|
||||
|
||||
// Macro to check return value of a ucol_* function call.
|
||||
#define COLLATOR_CHECK_STATUS( co, msg ) \
|
||||
|
@ -45,7 +45,7 @@ static void collator_ctor(INTERNAL_FUNCTION_PARAMETERS)
|
||||
}
|
||||
|
||||
INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
|
||||
co = (Collator_object *) zend_object_store_get_object( object TSRMLS_CC );
|
||||
COLLATOR_METHOD_FETCH_OBJECT;
|
||||
|
||||
if(locale_len == 0) {
|
||||
locale = intl_locale_get_default(TSRMLS_C);
|
||||
|
@ -17,8 +17,9 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php_intl.h"
|
||||
#include "intl_convert.h"
|
||||
#include "../php_intl.h"
|
||||
#include "dateformat_class.h"
|
||||
#include "../intl_convert.h"
|
||||
#include "dateformat_class.h"
|
||||
#include "dateformat_attr.h"
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "dateformat_attr.h"
|
||||
#include "dateformat_attrcpp.h"
|
||||
|
||||
#include <zend_exceptions.h>
|
||||
|
||||
zend_class_entry *IntlDateFormatter_ce_ptr = NULL;
|
||||
static zend_object_handlers IntlDateFormatter_handlers;
|
||||
|
||||
@ -90,18 +92,23 @@ zend_object_value IntlDateFormatter_object_clone(zval *object TSRMLS_DC)
|
||||
zend_object_handle handle = Z_OBJ_HANDLE_P(object);
|
||||
IntlDateFormatter_object *dfo, *new_dfo;
|
||||
|
||||
DATE_FORMAT_METHOD_FETCH_OBJECT;
|
||||
DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK;
|
||||
|
||||
new_obj_val = IntlDateFormatter_ce_ptr->create_object(IntlDateFormatter_ce_ptr TSRMLS_CC);
|
||||
new_dfo = (IntlDateFormatter_object *)zend_object_store_get_object_by_handle(new_obj_val.handle TSRMLS_CC);
|
||||
/* clone standard parts */
|
||||
zend_objects_clone_members(&new_dfo->zo, new_obj_val, &dfo->zo, handle TSRMLS_CC);
|
||||
/* clone formatter object */
|
||||
DATE_FORMAT_OBJECT(new_dfo) = udat_clone(DATE_FORMAT_OBJECT(dfo), &INTL_DATA_ERROR_CODE(new_dfo));
|
||||
if(U_FAILURE(INTL_DATA_ERROR_CODE(new_dfo))) {
|
||||
/* set up error in case error handler is interested */
|
||||
intl_error_set( NULL, INTL_DATA_ERROR_CODE(new_dfo), "Failed to clone IntlDateFormatter object", 0 TSRMLS_CC );
|
||||
IntlDateFormatter_object_dtor(new_dfo, new_obj_val.handle TSRMLS_CC); /* free new object */
|
||||
zend_error(E_ERROR, "Failed to clone IntlDateFormatter object");
|
||||
if (dfo->datef_data.udatf != NULL) {
|
||||
DATE_FORMAT_OBJECT(new_dfo) = udat_clone(DATE_FORMAT_OBJECT(dfo), &INTL_DATA_ERROR_CODE(dfo));
|
||||
if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
|
||||
/* set up error in case error handler is interested */
|
||||
intl_errors_set(INTL_DATA_ERROR_P(dfo), INTL_DATA_ERROR_CODE(dfo),
|
||||
"Failed to clone IntlDateFormatter object", 0 TSRMLS_CC );
|
||||
zend_throw_exception(NULL, "Failed to clone IntlDateFormatter object", 0 TSRMLS_CC);
|
||||
}
|
||||
} else {
|
||||
zend_throw_exception(NULL, "Cannot clone unconstructed IntlDateFormatter", 0 TSRMLS_CC);
|
||||
}
|
||||
return new_obj_val;
|
||||
}
|
||||
|
@ -38,7 +38,15 @@ extern zend_class_entry *IntlDateFormatter_ce_ptr;
|
||||
/* Auxiliary macros */
|
||||
|
||||
#define DATE_FORMAT_METHOD_INIT_VARS INTL_METHOD_INIT_VARS(IntlDateFormatter, dfo)
|
||||
#define DATE_FORMAT_METHOD_FETCH_OBJECT INTL_METHOD_FETCH_OBJECT(IntlDateFormatter, dfo)
|
||||
#define DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK INTL_METHOD_FETCH_OBJECT(IntlDateFormatter, dfo)
|
||||
#define DATE_FORMAT_METHOD_FETCH_OBJECT \
|
||||
DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; \
|
||||
if (dfo->datef_data.udatf == NULL) \
|
||||
{ \
|
||||
intl_errors_set(&dfo->datef_data.error, U_ILLEGAL_ARGUMENT_ERROR, "Found unconstructed IntlDateFormatter", 0 TSRMLS_CC); \
|
||||
RETURN_FALSE; \
|
||||
}
|
||||
|
||||
#define DATE_FORMAT_OBJECT(dfo) (dfo)->datef_data.udatf
|
||||
|
||||
#endif // #ifndef DATE_FORMAT_CLASS_H
|
||||
|
@ -76,7 +76,7 @@ static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
|
||||
}
|
||||
locale = Locale::createFromName(locale_str);
|
||||
|
||||
DATE_FORMAT_METHOD_FETCH_OBJECT;
|
||||
DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK;
|
||||
|
||||
if (DATE_FORMAT_OBJECT(dfo) != NULL) {
|
||||
intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR,
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "formatter_main.h"
|
||||
#include "formatter_attr.h"
|
||||
|
||||
#include <zend_exceptions.h>
|
||||
|
||||
zend_class_entry *NumberFormatter_ce_ptr = NULL;
|
||||
static zend_object_handlers NumberFormatter_handlers;
|
||||
|
||||
@ -83,18 +85,23 @@ zend_object_value NumberFormatter_object_clone(zval *object TSRMLS_DC)
|
||||
zend_object_handle handle = Z_OBJ_HANDLE_P(object);
|
||||
NumberFormatter_object *nfo, *new_nfo;
|
||||
|
||||
FORMATTER_METHOD_FETCH_OBJECT;
|
||||
FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK;
|
||||
new_obj_val = NumberFormatter_ce_ptr->create_object(NumberFormatter_ce_ptr TSRMLS_CC);
|
||||
new_nfo = (NumberFormatter_object *)zend_object_store_get_object_by_handle(new_obj_val.handle TSRMLS_CC);
|
||||
/* clone standard parts */
|
||||
zend_objects_clone_members(&new_nfo->zo, new_obj_val, &nfo->zo, handle TSRMLS_CC);
|
||||
/* clone formatter object */
|
||||
FORMATTER_OBJECT(new_nfo) = unum_clone(FORMATTER_OBJECT(nfo), &INTL_DATA_ERROR_CODE(new_nfo));
|
||||
if(U_FAILURE(INTL_DATA_ERROR_CODE(new_nfo))) {
|
||||
/* set up error in case error handler is interested */
|
||||
intl_error_set( NULL, INTL_DATA_ERROR_CODE(new_nfo), "Failed to clone NumberFormatter object", 0 TSRMLS_CC );
|
||||
NumberFormatter_object_dtor(new_nfo, new_obj_val.handle TSRMLS_CC); /* free new object */
|
||||
zend_error(E_ERROR, "Failed to clone NumberFormatter object");
|
||||
/* clone formatter object. It may fail, the destruction code must handle this case */
|
||||
if (FORMATTER_OBJECT(nfo) != NULL) {
|
||||
FORMATTER_OBJECT(new_nfo) = unum_clone(FORMATTER_OBJECT(nfo),
|
||||
&INTL_DATA_ERROR_CODE(nfo));
|
||||
if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) {
|
||||
/* set up error in case error handler is interested */
|
||||
intl_errors_set(INTL_DATA_ERROR_P(nfo), INTL_DATA_ERROR_CODE(nfo),
|
||||
"Failed to clone NumberFormatter object", 0 TSRMLS_CC);
|
||||
zend_throw_exception(NULL, "Failed to clone NumberFormatter object", 0 TSRMLS_CC);
|
||||
}
|
||||
} else {
|
||||
zend_throw_exception(NULL, "Cannot clone unconstructed NumberFormatter", 0 TSRMLS_CC);
|
||||
}
|
||||
return new_obj_val;
|
||||
}
|
||||
|
@ -34,8 +34,17 @@ extern zend_class_entry *NumberFormatter_ce_ptr;
|
||||
|
||||
/* Auxiliary macros */
|
||||
|
||||
#define FORMATTER_METHOD_INIT_VARS INTL_METHOD_INIT_VARS(NumberFormatter, nfo)
|
||||
#define FORMATTER_METHOD_FETCH_OBJECT INTL_METHOD_FETCH_OBJECT(NumberFormatter, nfo)
|
||||
#define FORMATTER_OBJECT(nfo) (nfo)->nf_data.unum
|
||||
#define FORMATTER_METHOD_INIT_VARS INTL_METHOD_INIT_VARS(NumberFormatter, nfo)
|
||||
#define FORMATTER_OBJECT(nfo) (nfo)->nf_data.unum
|
||||
#define FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK INTL_METHOD_FETCH_OBJECT(NumberFormatter, nfo)
|
||||
#define FORMATTER_METHOD_FETCH_OBJECT \
|
||||
FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK; \
|
||||
if (FORMATTER_OBJECT(nfo) == NULL) \
|
||||
{ \
|
||||
intl_errors_set(&nfo->nf_data.error, U_ILLEGAL_ARGUMENT_ERROR, \
|
||||
"Found unconstructed NumberFormatter", 0 TSRMLS_CC); \
|
||||
RETURN_FALSE; \
|
||||
}
|
||||
|
||||
|
||||
#endif // #ifndef FORMATTER_CLASS_H
|
||||
|
@ -47,7 +47,7 @@ static void numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
|
||||
|
||||
INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
|
||||
object = return_value;
|
||||
FORMATTER_METHOD_FETCH_OBJECT;
|
||||
FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK;
|
||||
|
||||
/* Convert pattern (if specified) to UTF-16. */
|
||||
if(pattern && pattern_len) {
|
||||
|
@ -49,7 +49,7 @@ static void msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
|
||||
}
|
||||
|
||||
INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
|
||||
MSG_FORMAT_METHOD_FETCH_OBJECT;
|
||||
MSG_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK;
|
||||
|
||||
/* Convert pattern (if specified) to UTF-16. */
|
||||
if(pattern && pattern_len) {
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "msgformat.h"
|
||||
#include "msgformat_attr.h"
|
||||
|
||||
#include <zend_exceptions.h>
|
||||
|
||||
zend_class_entry *MessageFormatter_ce_ptr = NULL;
|
||||
static zend_object_handlers MessageFormatter_handlers;
|
||||
|
||||
@ -81,18 +83,24 @@ zend_object_value MessageFormatter_object_clone(zval *object TSRMLS_DC)
|
||||
zend_object_handle handle = Z_OBJ_HANDLE_P(object);
|
||||
MessageFormatter_object *mfo, *new_mfo;
|
||||
|
||||
MSG_FORMAT_METHOD_FETCH_OBJECT;
|
||||
MSG_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK;
|
||||
new_obj_val = MessageFormatter_ce_ptr->create_object(MessageFormatter_ce_ptr TSRMLS_CC);
|
||||
new_mfo = (MessageFormatter_object *)zend_object_store_get_object_by_handle(new_obj_val.handle TSRMLS_CC);
|
||||
/* clone standard parts */
|
||||
zend_objects_clone_members(&new_mfo->zo, new_obj_val, &mfo->zo, handle TSRMLS_CC);
|
||||
|
||||
/* clone formatter object */
|
||||
MSG_FORMAT_OBJECT(new_mfo) = umsg_clone(MSG_FORMAT_OBJECT(mfo), &INTL_DATA_ERROR_CODE(new_mfo));
|
||||
if(U_FAILURE(INTL_DATA_ERROR_CODE(new_mfo))) {
|
||||
/* set up error in case error handler is interested */
|
||||
intl_error_set( NULL, INTL_DATA_ERROR_CODE(new_mfo), "Failed to clone MessageFormatter object", 0 TSRMLS_CC );
|
||||
MessageFormatter_object_dtor(new_mfo, new_obj_val.handle TSRMLS_CC); /* free new object */
|
||||
zend_error(E_ERROR, "Failed to clone MessageFormatter object");
|
||||
if (MSG_FORMAT_OBJECT(mfo) != NULL) {
|
||||
MSG_FORMAT_OBJECT(new_mfo) = umsg_clone(MSG_FORMAT_OBJECT(mfo),
|
||||
&INTL_DATA_ERROR_CODE(mfo));
|
||||
|
||||
if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) {
|
||||
intl_errors_set(INTL_DATA_ERROR_P(mfo), INTL_DATA_ERROR_CODE(mfo),
|
||||
"Failed to clone MessageFormatter object", 0 TSRMLS_CC);
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Failed to clone MessageFormatter object");
|
||||
}
|
||||
} else {
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Cannot clone unconstructed MessageFormatter");
|
||||
}
|
||||
return new_obj_val;
|
||||
}
|
||||
|
@ -37,7 +37,15 @@ extern zend_class_entry *MessageFormatter_ce_ptr;
|
||||
/* Auxiliary macros */
|
||||
|
||||
#define MSG_FORMAT_METHOD_INIT_VARS INTL_METHOD_INIT_VARS(MessageFormatter, mfo)
|
||||
#define MSG_FORMAT_METHOD_FETCH_OBJECT INTL_METHOD_FETCH_OBJECT(MessageFormatter, mfo)
|
||||
#define MSG_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK INTL_METHOD_FETCH_OBJECT(MessageFormatter, mfo)
|
||||
#define MSG_FORMAT_METHOD_FETCH_OBJECT \
|
||||
MSG_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; \
|
||||
if (MSG_FORMAT_OBJECT(mfo) == NULL) { \
|
||||
intl_errors_set(&mfo->mf_data.error, U_ILLEGAL_ARGUMENT_ERROR, \
|
||||
"Found unconstructed MessageFormatter", 0 TSRMLS_CC); \
|
||||
RETURN_FALSE; \
|
||||
}
|
||||
|
||||
#define MSG_FORMAT_OBJECT(mfo) (mfo)->mf_data.umsgf
|
||||
|
||||
#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM < 48
|
||||
|
@ -260,7 +260,14 @@ PHP_FUNCTION( resourcebundle_get )
|
||||
/* {{{ resourcebundle_array_count */
|
||||
int resourcebundle_array_count(zval *object, long *count TSRMLS_DC)
|
||||
{
|
||||
ResourceBundle_object *rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC);
|
||||
ResourceBundle_object *rb;
|
||||
RESOURCEBUNDLE_METHOD_FETCH_OBJECT_NO_CHECK;
|
||||
|
||||
if (rb->me == NULL) {
|
||||
intl_errors_set(&rb->error, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"Found unconstructed ResourceBundle", 0 TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*count = ures_getSize( rb->me );
|
||||
|
||||
|
@ -33,7 +33,16 @@ typedef struct {
|
||||
} ResourceBundle_object;
|
||||
|
||||
#define RESOURCEBUNDLE_METHOD_INIT_VARS INTL_METHOD_INIT_VARS(ResourceBundle, rb)
|
||||
#define RESOURCEBUNDLE_METHOD_FETCH_OBJECT INTL_METHOD_FETCH_OBJECT(ResourceBundle, rb)
|
||||
#define RESOURCEBUNDLE_METHOD_FETCH_OBJECT_NO_CHECK INTL_METHOD_FETCH_OBJECT(ResourceBundle, rb)
|
||||
#define RESOURCEBUNDLE_METHOD_FETCH_OBJECT \
|
||||
INTL_METHOD_FETCH_OBJECT(ResourceBundle, rb); \
|
||||
if (RESOURCEBUNDLE_OBJECT(rb) == NULL) { \
|
||||
intl_errors_set(&rb->error, U_ILLEGAL_ARGUMENT_ERROR, \
|
||||
"Found unconstructed ResourceBundle", 0 TSRMLS_CC); \
|
||||
RETURN_FALSE; \
|
||||
}
|
||||
|
||||
|
||||
#define RESOURCEBUNDLE_OBJECT(rb) (rb)->me
|
||||
|
||||
void resourcebundle_register_class( TSRMLS_D );
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "intl_common.h"
|
||||
#include "spoofchecker_create.h"
|
||||
#include "intl_error.h"
|
||||
#include "intl_data.h"
|
||||
|
||||
#include <unicode/uspoof.h>
|
||||
|
||||
@ -55,9 +56,14 @@ extern zend_class_entry *Spoofchecker_ce_ptr;
|
||||
Spoofchecker_object* co = NULL; \
|
||||
intl_error_reset(NULL TSRMLS_CC); \
|
||||
|
||||
#define SPOOFCHECKER_METHOD_FETCH_OBJECT \
|
||||
co = (Spoofchecker_object *) zend_object_store_get_object(object TSRMLS_CC); \
|
||||
intl_error_reset(SPOOFCHECKER_ERROR_P(co) TSRMLS_CC); \
|
||||
#define SPOOFCHECKER_METHOD_FETCH_OBJECT_NO_CHECK INTL_METHOD_FETCH_OBJECT(Spoofchecker, co)
|
||||
#define SPOOFCHECKER_METHOD_FETCH_OBJECT \
|
||||
SPOOFCHECKER_METHOD_FETCH_OBJECT_NO_CHECK; \
|
||||
if (co->uspoof == NULL) { \
|
||||
intl_errors_set(&co->err, U_ILLEGAL_ARGUMENT_ERROR, \
|
||||
"Found unconstructed Spoofchecker", 0 TSRMLS_CC); \
|
||||
RETURN_FALSE; \
|
||||
}
|
||||
|
||||
// Macro to check return value of a ucol_* function call.
|
||||
#define SPOOFCHECKER_CHECK_STATUS(co, msg) \
|
||||
|
@ -35,7 +35,7 @@ PHP_METHOD(Spoofchecker, __construct)
|
||||
return;
|
||||
}
|
||||
|
||||
SPOOFCHECKER_METHOD_FETCH_OBJECT;
|
||||
SPOOFCHECKER_METHOD_FETCH_OBJECT_NO_CHECK;
|
||||
|
||||
co->uspoof = uspoof_open(SPOOFCHECKER_ERROR_CODE_P(co));
|
||||
INTL_CTOR_CHECK_STATUS(co, "spoofchecker: unable to open ICU Spoof Checker");
|
||||
|
@ -1,49 +0,0 @@
|
||||
--TEST--
|
||||
Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #1
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
// port of Symfony's Symfony\Component\Locale\Tests\Stub\StubNumberFormatterTest#testFormatTypeInt32Intl
|
||||
|
||||
|
||||
// Crashes on Windows
|
||||
// Windows note: the popup '...program has stopped working'(AEDebug Popup)
|
||||
// doesn't always show if you're rapidly running this test repeatedly.
|
||||
// regardless of that, the test always crashes every time.
|
||||
// (it will show up the first time, or if you wait a while before running it again.)
|
||||
// (the popup may also be disabled, which can be done with a registry setting.)
|
||||
// you can confirm it crashed by checking the exit code OR
|
||||
// the message this test prints at the very end (expected output for pass).
|
||||
//
|
||||
// Get Exit Code
|
||||
// Linux: echo $?
|
||||
// Windows: echo %ErrorLevel%
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// PHP Unit's code to unserialize data passed as args to #testFormatTypeInt32Intl
|
||||
$unit_test_args = unserialize('a:3:{i:0;O:15:"NumberFormatter":0:{}i:1;i:1;i:2;s:1:"1";}');
|
||||
|
||||
var_dump($unit_test_args);
|
||||
|
||||
// execute the code from #testFormatTypeInt32Intl
|
||||
$unit_test_args[0]->format($unit_test_args[1], \NumberFormatter::TYPE_INT32);
|
||||
|
||||
echo "== didn't crash ==".PHP_EOL;
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(3) {
|
||||
[0]=>
|
||||
object(NumberFormatter)#1 (0) {
|
||||
}
|
||||
[1]=>
|
||||
int(1)
|
||||
[2]=>
|
||||
string(1) "1"
|
||||
}
|
||||
== didn't crash ==
|
@ -1,33 +0,0 @@
|
||||
--TEST--
|
||||
Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #2
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
// StubNumberFormatterTest#testFormatTypeInt32Intl is tested many times, each with different args.
|
||||
// there are 7 sets of args that crash PHP (and other args that don't), each of those 7 is now a separate PHPT test
|
||||
// to ensure that each of the 7 args are always tested.
|
||||
|
||||
// PHP Unit's code to unserialize data passed as args to #testFormatTypeInt32Intl
|
||||
$unit_test_args = unserialize('a:3:{i:0;O:15:"NumberFormatter":0:{}i:1;d:1.1000000000000001;i:2;s:1:"1";}');
|
||||
|
||||
var_dump($unit_test_args);
|
||||
|
||||
// execute the code from #testFormatTypeInt32Intl
|
||||
$unit_test_args[0]->format($unit_test_args[1], \NumberFormatter::TYPE_INT32);
|
||||
|
||||
echo "== didn't crash ==".PHP_EOL;
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(3) {
|
||||
[0]=>
|
||||
object(NumberFormatter)#1 (0) {
|
||||
}
|
||||
[1]=>
|
||||
float(1.1)
|
||||
[2]=>
|
||||
string(1) "1"
|
||||
}
|
||||
== didn't crash ==
|
@ -1,32 +0,0 @@
|
||||
--TEST--
|
||||
Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #3
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
// PHP Unit's code to unserialize data passed as args to #testFormatTypeInt32Intl
|
||||
$unit_test_args = unserialize('a:4:{i:0;O:15:"NumberFormatter":0:{}i:1;d:2147483648;i:2;s:14:"-2,147,483,648";i:3;s:83:"->format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range.";}');
|
||||
|
||||
var_dump($unit_test_args);
|
||||
|
||||
// execute the code from #testFormatTypeInt32Intl
|
||||
$unit_test_args[0]->format($unit_test_args[1], \NumberFormatter::TYPE_INT32);
|
||||
|
||||
echo "== didn't crash ==".PHP_EOL;
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(4) {
|
||||
[0]=>
|
||||
object(NumberFormatter)#1 (0) {
|
||||
}
|
||||
[1]=>
|
||||
float(2147483648)
|
||||
[2]=>
|
||||
string(14) "-2,147,483,648"
|
||||
[3]=>
|
||||
string(83) "->format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range."
|
||||
}
|
||||
== didn't crash ==
|
@ -1,30 +0,0 @@
|
||||
--TEST--
|
||||
Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #4
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
// PHP Unit's code to unserialize data passed as args to #testFormatTypeInt32Intl
|
||||
$unit_test_args = unserialize('a:3:{i:0;O:15:"NumberFormatter":0:{}i:1;i:1;i:2;s:7:"SFD1.00";}');
|
||||
|
||||
var_dump($unit_test_args);
|
||||
|
||||
// execute the code from #testFormatTypeInt32Intl
|
||||
$unit_test_args[0]->format($unit_test_args[1], \NumberFormatter::TYPE_INT32);
|
||||
|
||||
echo "== didn't crash ==".PHP_EOL;
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(3) {
|
||||
[0]=>
|
||||
object(NumberFormatter)#1 (0) {
|
||||
}
|
||||
[1]=>
|
||||
int(1)
|
||||
[2]=>
|
||||
string(7) "SFD1.00"
|
||||
}
|
||||
== didn't crash ==
|
@ -1,30 +0,0 @@
|
||||
--TEST--
|
||||
Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #5
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
// PHP Unit's code to unserialize data passed as args to #testFormatTypeInt32Intl
|
||||
$unit_test_args = unserialize('a:3:{i:0;O:15:"NumberFormatter":0:{}i:1;d:1.1000000000000001;i:2;s:7:"SFD1.00";}');
|
||||
|
||||
var_dump($unit_test_args);
|
||||
|
||||
// execute the code from #testFormatTypeInt32Intl
|
||||
$unit_test_args[0]->format($unit_test_args[1], \NumberFormatter::TYPE_INT32);
|
||||
|
||||
echo "== didn't crash ==".PHP_EOL;
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(3) {
|
||||
[0]=>
|
||||
object(NumberFormatter)#1 (0) {
|
||||
}
|
||||
[1]=>
|
||||
float(1.1)
|
||||
[2]=>
|
||||
string(7) "SFD1.00"
|
||||
}
|
||||
== didn't crash ==
|
@ -1,32 +0,0 @@
|
||||
--TEST--
|
||||
Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #6
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
// PHP Unit's code to unserialize data passed as args to #testFormatTypeInt32Intl
|
||||
$unit_test_args = unserialize('a:4:{i:0;O:15:"NumberFormatter":0:{}i:1;d:2147483648;i:2;s:21:"(SFD2,147,483,648.00)";i:3;s:83:"->format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range.";}');
|
||||
|
||||
var_dump($unit_test_args);
|
||||
|
||||
// execute the code from #testFormatTypeInt32Intl
|
||||
$unit_test_args[0]->format($unit_test_args[1], \NumberFormatter::TYPE_INT32);
|
||||
|
||||
echo "== didn't crash ==".PHP_EOL;
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(4) {
|
||||
[0]=>
|
||||
object(NumberFormatter)#1 (0) {
|
||||
}
|
||||
[1]=>
|
||||
float(2147483648)
|
||||
[2]=>
|
||||
string(21) "(SFD2,147,483,648.00)"
|
||||
[3]=>
|
||||
string(83) "->format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range."
|
||||
}
|
||||
== didn't crash ==
|
@ -1,32 +0,0 @@
|
||||
--TEST--
|
||||
Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #7
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
// PHP Unit's code to unserialize data passed as args to #testFormatTypeInt32Intl
|
||||
$unit_test_args = unserialize('a:4:{i:0;O:15:"NumberFormatter":0:{}i:1;d:-2147483649;i:2;s:19:"SFD2,147,483,647.00";i:3;s:83:"->format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range.";}');
|
||||
|
||||
var_dump($unit_test_args);
|
||||
|
||||
// execute the code from #testFormatTypeInt32Intl
|
||||
$unit_test_args[0]->format($unit_test_args[1], \NumberFormatter::TYPE_INT32);
|
||||
|
||||
echo "== didn't crash ==".PHP_EOL;
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(4) {
|
||||
[0]=>
|
||||
object(NumberFormatter)#1 (0) {
|
||||
}
|
||||
[1]=>
|
||||
float(-2147483649)
|
||||
[2]=>
|
||||
string(19) "SFD2,147,483,647.00"
|
||||
[3]=>
|
||||
string(83) "->format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range."
|
||||
}
|
||||
== didn't crash ==
|
20
ext/intl/tests/dateformat_clone_bad_obj.phpt
Normal file
20
ext/intl/tests/dateformat_clone_bad_obj.phpt
Normal file
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Cloning unconstructed IntlDateFormatter
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A extends IntlDateFormatter {
|
||||
function __construct() {}
|
||||
}
|
||||
|
||||
$a = new A;
|
||||
try {
|
||||
$b = clone $a;
|
||||
} catch (Exception $e) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
|
||||
--EXPECTF--
|
||||
string(%s) "Cannot clone unconstructed IntlDateFormatter"
|
20
ext/intl/tests/formatter_clone_bad_obj.phpt
Normal file
20
ext/intl/tests/formatter_clone_bad_obj.phpt
Normal file
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Cloning unconstructed numfmt
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A extends NumberFormatter {
|
||||
function __construct() {}
|
||||
}
|
||||
|
||||
$a = new A;
|
||||
try {
|
||||
$b = clone $a;
|
||||
} catch (Exception $e) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
|
||||
--EXPECTF--
|
||||
string(42) "Cannot clone unconstructed NumberFormatter"
|
20
ext/intl/tests/msgfmt_clone_bad_obj.phpt
Normal file
20
ext/intl/tests/msgfmt_clone_bad_obj.phpt
Normal file
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Cloning unconstructed MessageFormatter
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A extends MessageFormatter {
|
||||
function __construct() {}
|
||||
}
|
||||
|
||||
$a = new A;
|
||||
try {
|
||||
$b = clone $a;
|
||||
} catch (Exception $e) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
|
||||
--EXPECTF--
|
||||
string(%d) "Cannot clone unconstructed MessageFormatter"
|
@ -2,7 +2,6 @@
|
||||
LOAD DATA INFILE - open_basedir
|
||||
--SKIPIF--
|
||||
<?php
|
||||
@include_once("connect.inc");
|
||||
include_once('skipif.inc');
|
||||
include_once('skipifconnectfailure.inc');
|
||||
|
||||
|
@ -778,6 +778,11 @@ PHP_FUNCTION(mysqli_poll)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (!r_array && !e_array) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No stream arrays were passed");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (r_array != NULL) {
|
||||
mysqlnd_zval_array_to_mysqlnd_array(r_array, &new_r_array TSRMLS_CC);
|
||||
}
|
||||
|
26
ext/mysqli/tests/bug62885.phpt
Normal file
26
ext/mysqli/tests/bug62885.phpt
Normal file
@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
Bug #62885 (mysqli_poll - Segmentation fault)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once("connect.inc");
|
||||
if (!$IS_MYSQLND) {
|
||||
die("skip mysqlnd only test");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
error_reporting(E_ALL);
|
||||
$tablica = array();
|
||||
$test1 = mysqli_poll($test2, $test3, $tablica, null);
|
||||
|
||||
$test2 = array();
|
||||
$test2 = array();
|
||||
$test1 = mysqli_poll($test2, $test3, $tablica, null);
|
||||
echo "okey";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: mysqli_poll(): No stream arrays were passed in %sbug62885.php on line %d
|
||||
|
||||
Warning: mysqli_poll(): No stream arrays were passed in %sbug62885.php on line %d
|
||||
okey
|
@ -622,19 +622,19 @@ mysqlnd_run_authentication(
|
||||
}
|
||||
DBG_INF_FMT("conn->error_info->error_no = %d", conn->error_info->error_no);
|
||||
} while (ret == FAIL && conn->error_info->error_no == 0 && switch_to_auth_protocol != NULL);
|
||||
if (plugin_data) {
|
||||
mnd_efree(plugin_data);
|
||||
}
|
||||
|
||||
if (ret == PASS) {
|
||||
DBG_INF_FMT("saving requested_protocol=%s", requested_protocol);
|
||||
conn->m->set_client_option(conn, MYSQLND_OPT_AUTH_PROTOCOL, requested_protocol TSRMLS_CC);
|
||||
}
|
||||
|
||||
end:
|
||||
if (plugin_data) {
|
||||
mnd_efree(plugin_data);
|
||||
}
|
||||
if (requested_protocol) {
|
||||
mnd_efree(requested_protocol);
|
||||
}
|
||||
end:
|
||||
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
@ -838,6 +838,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
|
||||
MYSQLND_NET * net = conn->net;
|
||||
|
||||
DBG_ENTER("mysqlnd_conn_data::connect");
|
||||
DBG_INF_FMT("conn=%p", conn);
|
||||
|
||||
if (PASS != conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
|
||||
goto err;
|
||||
@ -1149,7 +1150,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, query)(MYSQLND_CONN_DATA * conn, const char *
|
||||
size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, query);
|
||||
enum_func_status ret = FAIL;
|
||||
DBG_ENTER("mysqlnd_conn_data::query");
|
||||
DBG_INF_FMT("conn=%llu query=%s", conn->thread_id, query);
|
||||
DBG_INF_FMT("conn=%p conn=%llu query=%s", conn, conn->thread_id, query);
|
||||
|
||||
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
|
||||
if (PASS == conn->m->send_query(conn, query, query_len TSRMLS_CC) &&
|
||||
@ -1883,10 +1884,10 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn TSR
|
||||
Fall-through
|
||||
*/
|
||||
CONN_SET_STATE(conn, CONN_QUIT_SENT);
|
||||
net->data->m.close_stream(net, conn->stats, conn->error_info TSRMLS_CC);
|
||||
/* Fall-through */
|
||||
case CONN_QUIT_SENT:
|
||||
/* The user has killed its own connection */
|
||||
net->data->m.close_stream(net, conn->stats, conn->error_info TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2446,7 +2447,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn T
|
||||
MYSQLND_RES * result = NULL;
|
||||
|
||||
DBG_ENTER("mysqlnd_conn_data::store_result");
|
||||
DBG_INF_FMT("conn=%llu", conn->thread_id);
|
||||
DBG_INF_FMT("conn=%llu conn=%p", conn->thread_id, conn);
|
||||
|
||||
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
|
||||
do {
|
||||
|
@ -8,6 +8,7 @@ if (false == $dir) die('skip no driver');
|
||||
if (!strncasecmp(getenv('PDOTEST_DSN'), 'sqlite', strlen('sqlite'))) die('skip not relevant for sqlite driver');
|
||||
if (!strncasecmp(getenv('PDOTEST_DSN'), 'pgsql', strlen('pgsql'))) die('skip not relevant for pgsql driver');
|
||||
if (!strncasecmp(getenv('PDOTEST_DSN'), 'oci', strlen('oci'))) die('skip not relevant for oci driver - Hyphen is not legal for bind names in Oracle DB');
|
||||
if (!strncasecmp(getenv('PDOTEST_DSN'), 'firebird', strlen('firebird'))) die('skip not relevant for firebird driver');
|
||||
require_once $dir . 'pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
|
@ -2647,11 +2647,8 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert,
|
||||
len = -len;
|
||||
}
|
||||
user_stub = 0;
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (!(len = php_stream_copy_to_mem(stubfile, (void **) &user_stub, len, 0)) || !user_stub) {
|
||||
#else
|
||||
|
||||
if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) {
|
||||
#endif
|
||||
if (closeoldfile) {
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
|
@ -58,9 +58,6 @@ static int phar_file_type(HashTable *mimes, char *file, char **mime_type TSRMLS_
|
||||
|
||||
static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char *basename, int request_uri_len TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
int is_unicode = 0;
|
||||
#endif
|
||||
HashTable *_SERVER;
|
||||
zval **stuff;
|
||||
char *path_info;
|
||||
@ -76,18 +73,7 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char
|
||||
_SERVER = Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]);
|
||||
|
||||
/* PATH_INFO and PATH_TRANSLATED should always be munged */
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (phar_find_key(_SERVER, "PATH_INFO", sizeof("PATH_INFO"), (void **) &stuff TSRMLS_CC)) {
|
||||
if (Z_TYPE_PP(stuff) == IS_UNICODE) {
|
||||
is_unicode = 1;
|
||||
zval_unicode_to_string(*stuff TSRMLS_CC);
|
||||
} else {
|
||||
is_unicode = 0;
|
||||
}
|
||||
#else
|
||||
if (SUCCESS == zend_hash_find(_SERVER, "PATH_INFO", sizeof("PATH_INFO"), (void **) &stuff)) {
|
||||
#endif
|
||||
|
||||
path_info = Z_STRVAL_PP(stuff);
|
||||
code = Z_STRLEN_PP(stuff);
|
||||
|
||||
@ -96,38 +82,19 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char
|
||||
|
||||
MAKE_STD_ZVAL(temp);
|
||||
ZVAL_STRINGL(temp, path_info, code, 0);
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (is_unicode) {
|
||||
zval_string_to_unicode(*stuff TSRMLS_CC);
|
||||
}
|
||||
#endif
|
||||
|
||||
zend_hash_update(_SERVER, "PHAR_PATH_INFO", sizeof("PHAR_PATH_INFO"), &temp, sizeof(zval **), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (phar_find_key(_SERVER, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED"), (void **) &stuff TSRMLS_CC)) {
|
||||
if (Z_TYPE_PP(stuff) == IS_UNICODE) {
|
||||
is_unicode = 1;
|
||||
zval_unicode_to_string(*stuff TSRMLS_CC);
|
||||
} else {
|
||||
is_unicode = 0;
|
||||
}
|
||||
#else
|
||||
if (SUCCESS == zend_hash_find(_SERVER, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED"), (void **) &stuff)) {
|
||||
#endif
|
||||
|
||||
path_info = Z_STRVAL_PP(stuff);
|
||||
code = Z_STRLEN_PP(stuff);
|
||||
Z_STRLEN_PP(stuff) = spprintf(&(Z_STRVAL_PP(stuff)), 4096, "phar://%s%s", fname, entry);
|
||||
|
||||
MAKE_STD_ZVAL(temp);
|
||||
ZVAL_STRINGL(temp, path_info, code, 0);
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (is_unicode) {
|
||||
zval_string_to_unicode(*stuff TSRMLS_CC);
|
||||
}
|
||||
#endif
|
||||
|
||||
zend_hash_update(_SERVER, "PHAR_PATH_TRANSLATED", sizeof("PHAR_PATH_TRANSLATED"), (void *) &temp, sizeof(zval **), NULL);
|
||||
}
|
||||
|
||||
@ -136,18 +103,7 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char
|
||||
}
|
||||
|
||||
if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_REQUEST_URI) {
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (phar_find_key(_SERVER, "REQUEST_URI", sizeof("REQUEST_URI"), (void **) &stuff TSRMLS_CC)) {
|
||||
if (Z_TYPE_PP(stuff) == IS_UNICODE) {
|
||||
is_unicode = 1;
|
||||
zval_unicode_to_string(*stuff TSRMLS_CC);
|
||||
} else {
|
||||
is_unicode = 0;
|
||||
}
|
||||
#else
|
||||
if (SUCCESS == zend_hash_find(_SERVER, "REQUEST_URI", sizeof("REQUEST_URI"), (void **) &stuff)) {
|
||||
#endif
|
||||
|
||||
path_info = Z_STRVAL_PP(stuff);
|
||||
code = Z_STRLEN_PP(stuff);
|
||||
|
||||
@ -156,29 +112,14 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char
|
||||
|
||||
MAKE_STD_ZVAL(temp);
|
||||
ZVAL_STRINGL(temp, path_info, code, 0);
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (is_unicode) {
|
||||
zval_string_to_unicode(*stuff TSRMLS_CC);
|
||||
}
|
||||
#endif
|
||||
|
||||
zend_hash_update(_SERVER, "PHAR_REQUEST_URI", sizeof("PHAR_REQUEST_URI"), (void *) &temp, sizeof(zval **), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_PHP_SELF) {
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (phar_find_key(_SERVER, "PHP_SELF", sizeof("PHP_SELF"), (void **) &stuff TSRMLS_CC)) {
|
||||
if (Z_TYPE_PP(stuff) == IS_UNICODE) {
|
||||
is_unicode = 1;
|
||||
zval_unicode_to_string(*stuff TSRMLS_CC);
|
||||
} else {
|
||||
is_unicode = 0;
|
||||
}
|
||||
#else
|
||||
if (SUCCESS == zend_hash_find(_SERVER, "PHP_SELF", sizeof("PHP_SELF"), (void **) &stuff)) {
|
||||
#endif
|
||||
|
||||
path_info = Z_STRVAL_PP(stuff);
|
||||
code = Z_STRLEN_PP(stuff);
|
||||
|
||||
@ -187,68 +128,34 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char
|
||||
|
||||
MAKE_STD_ZVAL(temp);
|
||||
ZVAL_STRINGL(temp, path_info, code, 0);
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (is_unicode) {
|
||||
zval_string_to_unicode(*stuff TSRMLS_CC);
|
||||
}
|
||||
#endif
|
||||
|
||||
zend_hash_update(_SERVER, "PHAR_PHP_SELF", sizeof("PHAR_PHP_SELF"), (void *) &temp, sizeof(zval **), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_SCRIPT_NAME) {
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (phar_find_key(_SERVER, "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void **) &stuff TSRMLS_CC)) {
|
||||
if (Z_TYPE_PP(stuff) == IS_UNICODE) {
|
||||
is_unicode = 1;
|
||||
zval_unicode_to_string(*stuff TSRMLS_CC);
|
||||
} else {
|
||||
is_unicode = 0;
|
||||
}
|
||||
#else
|
||||
if (SUCCESS == zend_hash_find(_SERVER, "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void **) &stuff)) {
|
||||
#endif
|
||||
|
||||
path_info = Z_STRVAL_PP(stuff);
|
||||
code = Z_STRLEN_PP(stuff);
|
||||
ZVAL_STRINGL(*stuff, entry, entry_len, 1);
|
||||
|
||||
MAKE_STD_ZVAL(temp);
|
||||
ZVAL_STRINGL(temp, path_info, code, 0);
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (is_unicode) {
|
||||
zval_string_to_unicode(*stuff TSRMLS_CC);
|
||||
}
|
||||
#endif
|
||||
|
||||
zend_hash_update(_SERVER, "PHAR_SCRIPT_NAME", sizeof("PHAR_SCRIPT_NAME"), (void *) &temp, sizeof(zval **), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_SCRIPT_FILENAME) {
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (phar_find_key(_SERVER, "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &stuff TSRMLS_CC)) {
|
||||
if (Z_TYPE_PP(stuff) == IS_UNICODE) {
|
||||
is_unicode = 1;
|
||||
zval_unicode_to_string(*stuff TSRMLS_CC);
|
||||
} else {
|
||||
is_unicode = 0;
|
||||
}
|
||||
#else
|
||||
if (SUCCESS == zend_hash_find(_SERVER, "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &stuff)) {
|
||||
#endif
|
||||
|
||||
path_info = Z_STRVAL_PP(stuff);
|
||||
code = Z_STRLEN_PP(stuff);
|
||||
Z_STRLEN_PP(stuff) = spprintf(&(Z_STRVAL_PP(stuff)), 4096, "phar://%s%s", fname, entry);
|
||||
|
||||
MAKE_STD_ZVAL(temp);
|
||||
ZVAL_STRINGL(temp, path_info, code, 0);
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (is_unicode) {
|
||||
zval_string_to_unicode(*stuff TSRMLS_CC);
|
||||
}
|
||||
#endif
|
||||
|
||||
zend_hash_update(_SERVER, "PHAR_SCRIPT_FILENAME", sizeof("PHAR_SCRIPT_FILENAME"), (void *) &temp, sizeof(zval **), NULL);
|
||||
}
|
||||
}
|
||||
@ -942,11 +849,7 @@ PHP_METHOD(Phar, webPhar)
|
||||
if (ext) {
|
||||
++ext;
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (phar_find_key(Z_ARRVAL_P(mimeoverride), ext, strlen(ext)+1, (void **) &val TSRMLS_CC)) {
|
||||
#else
|
||||
if (SUCCESS == zend_hash_find(Z_ARRVAL_P(mimeoverride), ext, strlen(ext)+1, (void **) &val)) {
|
||||
#endif
|
||||
switch (Z_TYPE_PP(val)) {
|
||||
case IS_LONG:
|
||||
if (Z_LVAL_PP(val) == PHAR_MIME_PHP || Z_LVAL_PP(val) == PHAR_MIME_PHPS) {
|
||||
@ -960,11 +863,6 @@ PHP_METHOD(Phar, webPhar)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
break;
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
case IS_UNICODE:
|
||||
zval_unicode_to_string(*(val) TSRMLS_CC);
|
||||
/* break intentionally omitted */
|
||||
#endif
|
||||
case IS_STRING:
|
||||
mime_type = Z_STRVAL_PP(val);
|
||||
code = PHAR_MIME_OTHER;
|
||||
@ -1015,26 +913,12 @@ PHP_METHOD(Phar, mungServer)
|
||||
|
||||
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(mungvalues)); SUCCESS == zend_hash_has_more_elements(Z_ARRVAL_P(mungvalues)); zend_hash_move_forward(Z_ARRVAL_P(mungvalues))) {
|
||||
zval **data = NULL;
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
zval *unicopy = NULL;
|
||||
#endif
|
||||
|
||||
if (SUCCESS != zend_hash_get_current_data(Z_ARRVAL_P(mungvalues), (void **) &data)) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "unable to retrieve array value in Phar::mungServer()");
|
||||
return;
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (Z_TYPE_PP(data) == IS_UNICODE) {
|
||||
MAKE_STD_ZVAL(unicopy);
|
||||
*unicopy = **data;
|
||||
zval_copy_ctor(unicopy);
|
||||
INIT_PZVAL(unicopy);
|
||||
zval_unicode_to_string(unicopy TSRMLS_CC);
|
||||
data = &unicopy;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Z_TYPE_PP(data) != IS_STRING) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Non-string value passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME");
|
||||
return;
|
||||
@ -1056,11 +940,6 @@ PHP_METHOD(Phar, mungServer)
|
||||
if (Z_STRLEN_PP(data) == sizeof("SCRIPT_FILENAME")-1 && !strncmp(Z_STRVAL_PP(data), "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME")-1)) {
|
||||
PHAR_GLOBALS->phar_SERVER_mung_list |= PHAR_MUNG_SCRIPT_FILENAME;
|
||||
}
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (unicopy) {
|
||||
zval_ptr_dtor(&unicopy);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@ -5037,11 +4916,7 @@ PHP_METHOD(PharFileInfo, getContent)
|
||||
|
||||
phar_seek_efp(link, 0, SEEK_SET, 0, 0 TSRMLS_CC);
|
||||
Z_TYPE_P(return_value) = IS_STRING;
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
Z_STRLEN_P(return_value) = php_stream_copy_to_mem(fp, (void **) &(Z_STRVAL_P(return_value)), link->uncompressed_filesize, 0);
|
||||
#else
|
||||
Z_STRLEN_P(return_value) = php_stream_copy_to_mem(fp, &(Z_STRVAL_P(return_value)), link->uncompressed_filesize, 0);
|
||||
#endif
|
||||
|
||||
if (!Z_STRVAL_P(return_value)) {
|
||||
Z_STRVAL_P(return_value) = estrndup("", 0);
|
||||
|
@ -207,30 +207,19 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat
|
||||
fpf = php_stream_alloc(&phar_ops, idata, NULL, mode);
|
||||
php_url_free(resource);
|
||||
efree(internal_file);
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (context && context->options && phar_find_key(HASH_OF(context->options), "phar", sizeof("phar"), (void**)&pzoption TSRMLS_CC)) {
|
||||
#else
|
||||
|
||||
if (context && context->options && zend_hash_find(HASH_OF(context->options), "phar", sizeof("phar"), (void**)&pzoption) == SUCCESS) {
|
||||
#endif
|
||||
pharcontext = HASH_OF(*pzoption);
|
||||
if (idata->internal_file->uncompressed_filesize == 0
|
||||
&& idata->internal_file->compressed_filesize == 0
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
&& phar_find_key(pharcontext, "compress", sizeof("compress"), (void**)&pzoption TSRMLS_CC)
|
||||
#else
|
||||
&& zend_hash_find(pharcontext, "compress", sizeof("compress"), (void**)&pzoption) == SUCCESS
|
||||
#endif
|
||||
&& Z_TYPE_PP(pzoption) == IS_LONG
|
||||
&& (Z_LVAL_PP(pzoption) & ~PHAR_ENT_COMPRESSION_MASK) == 0
|
||||
) {
|
||||
idata->internal_file->flags &= ~PHAR_ENT_COMPRESSION_MASK;
|
||||
idata->internal_file->flags |= Z_LVAL_PP(pzoption);
|
||||
}
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (phar_find_key(pharcontext, "metadata", sizeof("metadata"), (void**)&pzoption TSRMLS_CC)) {
|
||||
#else
|
||||
if (zend_hash_find(pharcontext, "metadata", sizeof("metadata"), (void**)&pzoption) == SUCCESS) {
|
||||
#endif
|
||||
if (idata->internal_file->metadata) {
|
||||
zval_ptr_dtor(&idata->internal_file->metadata);
|
||||
idata->internal_file->metadata = NULL;
|
||||
|
@ -986,11 +986,8 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
len = -len;
|
||||
}
|
||||
user_stub = 0;
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (!(len = php_stream_copy_to_mem(stubfile, (void **) &user_stub, len, 0)) || !user_stub) {
|
||||
#else
|
||||
|
||||
if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) {
|
||||
#endif
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to read resource to copy stub to new tar-based phar \"%s\"", phar->fname);
|
||||
}
|
||||
|
@ -603,11 +603,7 @@ foundit:
|
||||
|
||||
php_stream_filter_append(&fp->readfilters, filter);
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, (void **) &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
|
||||
#else
|
||||
if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
|
||||
#endif
|
||||
pefree(entry.filename, entry.is_persistent);
|
||||
#if PHP_VERSION_ID < 50207
|
||||
PHAR_ZIP_FAIL("unable to read in alias, truncated (PHP 5.2.7 and newer has a potential fix for this problem)");
|
||||
@ -628,11 +624,7 @@ foundit:
|
||||
|
||||
php_stream_filter_append(&fp->readfilters, filter);
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, (void **) &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
|
||||
#else
|
||||
if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
|
||||
#endif
|
||||
pefree(entry.filename, entry.is_persistent);
|
||||
#if PHP_VERSION_ID < 50207
|
||||
PHAR_ZIP_FAIL("unable to read in alias, truncated (PHP 5.2.7 and newer has a potential fix for this problem)");
|
||||
@ -643,11 +635,7 @@ foundit:
|
||||
php_stream_filter_flush(filter, 1);
|
||||
php_stream_filter_remove(filter, 1 TSRMLS_CC);
|
||||
} else {
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, (void **) &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
|
||||
#else
|
||||
if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
|
||||
#endif
|
||||
pefree(entry.filename, entry.is_persistent);
|
||||
PHAR_ZIP_FAIL("unable to read in alias, truncated");
|
||||
}
|
||||
@ -1252,11 +1240,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
|
||||
user_stub = 0;
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 6
|
||||
if (!(len = php_stream_copy_to_mem(stubfile, (void **) &user_stub, len, 0)) || !user_stub) {
|
||||
#else
|
||||
if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) {
|
||||
#endif
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to read resource to copy stub to new zip-based phar \"%s\"", phar->fname);
|
||||
}
|
||||
|
@ -4464,8 +4464,10 @@ ZEND_METHOD(reflection_class, getTraitAliases)
|
||||
int method_name_len;
|
||||
zend_trait_method_reference *cur_ref = ce->trait_aliases[i]->trait_method;
|
||||
|
||||
method_name_len = spprintf(&method_name, 0, "%s::%s", cur_ref->class_name, cur_ref->method_name);
|
||||
add_assoc_stringl_ex(return_value, ce->trait_aliases[i]->alias, ce->trait_aliases[i]->alias_len + 1, method_name, method_name_len, 0);
|
||||
if (ce->trait_aliases[i]->alias) {
|
||||
method_name_len = spprintf(&method_name, 0, "%s::%s", cur_ref->class_name, cur_ref->method_name);
|
||||
add_assoc_stringl_ex(return_value, ce->trait_aliases[i]->alias, ce->trait_aliases[i]->alias_len + 1, method_name, method_name_len, 0);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,10 @@ PHPAPI zend_class_entry *spl_ce_RecursiveArrayIterator;
|
||||
#define SPL_ARRAY_INT_MASK 0xFFFF0000
|
||||
#define SPL_ARRAY_CLONE_MASK 0x0300FFFF
|
||||
|
||||
#define SPL_ARRAY_METHOD_NO_ARG 0
|
||||
#define SPL_ARRAY_METHOD_USE_ARG 1
|
||||
#define SPL_ARRAY_METHOD_MAY_USER_ARG 2
|
||||
|
||||
typedef struct _spl_array_object {
|
||||
zend_object std;
|
||||
zval *array;
|
||||
@ -1426,14 +1430,28 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
|
||||
{
|
||||
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
|
||||
zval *tmp, *arg;
|
||||
zval *tmp, *arg = NULL;
|
||||
zval *retval_ptr = NULL;
|
||||
|
||||
MAKE_STD_ZVAL(tmp);
|
||||
Z_TYPE_P(tmp) = IS_ARRAY;
|
||||
Z_ARRVAL_P(tmp) = aht;
|
||||
|
||||
if (use_arg) {
|
||||
if (!use_arg) {
|
||||
aht->nApplyCount++;
|
||||
zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, 1, tmp, NULL TSRMLS_CC);
|
||||
aht->nApplyCount--;
|
||||
} else if (use_arg == SPL_ARRAY_METHOD_MAY_USER_ARG) {
|
||||
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "|z", &arg) == FAILURE) {
|
||||
Z_TYPE_P(tmp) = IS_NULL;
|
||||
zval_ptr_dtor(&tmp);
|
||||
zend_throw_exception(spl_ce_BadMethodCallException, "Function expects one argument at most", 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
aht->nApplyCount++;
|
||||
zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, arg? 2 : 1, tmp, arg TSRMLS_CC);
|
||||
aht->nApplyCount--;
|
||||
} else {
|
||||
if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
|
||||
Z_TYPE_P(tmp) = IS_NULL;
|
||||
zval_ptr_dtor(&tmp);
|
||||
@ -1443,10 +1461,6 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
|
||||
aht->nApplyCount++;
|
||||
zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, 2, tmp, arg TSRMLS_CC);
|
||||
aht->nApplyCount--;
|
||||
} else {
|
||||
aht->nApplyCount++;
|
||||
zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, 1, tmp, NULL TSRMLS_CC);
|
||||
aht->nApplyCount--;
|
||||
}
|
||||
Z_TYPE_P(tmp) = IS_NULL; /* we want to destroy the zval, not the hashtable */
|
||||
zval_ptr_dtor(&tmp);
|
||||
@ -1461,35 +1475,35 @@ SPL_METHOD(cname, fname) \
|
||||
spl_array_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, #fname, sizeof(#fname)-1, use_arg); \
|
||||
}
|
||||
|
||||
/* {{{ proto int ArrayObject::asort()
|
||||
proto int ArrayIterator::asort()
|
||||
/* {{{ proto int ArrayObject::asort([int $sort_flags = SORT_REGULAR ])
|
||||
proto int ArrayIterator::asort([int $sort_flags = SORT_REGULAR ])
|
||||
Sort the entries by values. */
|
||||
SPL_ARRAY_METHOD(Array, asort, 0) /* }}} */
|
||||
SPL_ARRAY_METHOD(Array, asort, SPL_ARRAY_METHOD_MAY_USER_ARG) /* }}} */
|
||||
|
||||
/* {{{ proto int ArrayObject::ksort()
|
||||
proto int ArrayIterator::ksort()
|
||||
/* {{{ proto int ArrayObject::ksort([int $sort_flags = SORT_REGULAR ])
|
||||
proto int ArrayIterator::ksort([int $sort_flags = SORT_REGULAR ])
|
||||
Sort the entries by key. */
|
||||
SPL_ARRAY_METHOD(Array, ksort, 0) /* }}} */
|
||||
SPL_ARRAY_METHOD(Array, ksort, SPL_ARRAY_METHOD_MAY_USER_ARG) /* }}} */
|
||||
|
||||
/* {{{ proto int ArrayObject::uasort(callback cmp_function)
|
||||
proto int ArrayIterator::uasort(callback cmp_function)
|
||||
Sort the entries by values user defined function. */
|
||||
SPL_ARRAY_METHOD(Array, uasort, 1) /* }}} */
|
||||
SPL_ARRAY_METHOD(Array, uasort, SPL_ARRAY_METHOD_USE_ARG) /* }}} */
|
||||
|
||||
/* {{{ proto int ArrayObject::uksort(callback cmp_function)
|
||||
proto int ArrayIterator::uksort(callback cmp_function)
|
||||
Sort the entries by key using user defined function. */
|
||||
SPL_ARRAY_METHOD(Array, uksort, 1) /* }}} */
|
||||
SPL_ARRAY_METHOD(Array, uksort, SPL_ARRAY_METHOD_USE_ARG) /* }}} */
|
||||
|
||||
/* {{{ proto int ArrayObject::natsort()
|
||||
proto int ArrayIterator::natsort()
|
||||
Sort the entries by values using "natural order" algorithm. */
|
||||
SPL_ARRAY_METHOD(Array, natsort, 0) /* }}} */
|
||||
SPL_ARRAY_METHOD(Array, natsort, SPL_ARRAY_METHOD_NO_ARG) /* }}} */
|
||||
|
||||
/* {{{ proto int ArrayObject::natcasesort()
|
||||
proto int ArrayIterator::natcasesort()
|
||||
Sort the entries by key using case insensitive "natural order" algorithm. */
|
||||
SPL_ARRAY_METHOD(Array, natcasesort, 0) /* }}} */
|
||||
SPL_ARRAY_METHOD(Array, natcasesort, SPL_ARRAY_METHOD_NO_ARG) /* }}} */
|
||||
|
||||
/* {{{ proto mixed|NULL ArrayIterator::current()
|
||||
Return current array entry */
|
||||
|
@ -223,10 +223,14 @@ static zend_object_value spl_fixedarray_object_new_ex(zend_class_entry *class_ty
|
||||
if (orig && clone_orig) {
|
||||
spl_fixedarray_object *other = (spl_fixedarray_object*)zend_object_store_get_object(orig TSRMLS_CC);
|
||||
intern->ce_get_iterator = other->ce_get_iterator;
|
||||
|
||||
intern->array = emalloc(sizeof(spl_fixedarray));
|
||||
spl_fixedarray_init(intern->array, other->array->size TSRMLS_CC);
|
||||
spl_fixedarray_copy(intern->array, other->array TSRMLS_CC);
|
||||
if (!other->array) {
|
||||
/* leave a empty object, will be dtor later by CLONE handler */
|
||||
zend_throw_exception(spl_ce_RuntimeException, "The instance wasn't initialized properly", 0 TSRMLS_CC);
|
||||
} else {
|
||||
intern->array = emalloc(sizeof(spl_fixedarray));
|
||||
spl_fixedarray_init(intern->array, other->array->size TSRMLS_CC);
|
||||
spl_fixedarray_copy(intern->array, other->array TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
while (parent) {
|
||||
|
@ -17,12 +17,14 @@ var_dump($ao1->asort());
|
||||
var_dump($ao1);
|
||||
var_dump($ao2->asort('blah'));
|
||||
var_dump($ao2);
|
||||
var_dump($ao2->asort(SORT_NUMERIC));
|
||||
var_dump($ao2);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
*** Testing ArrayObject::asort() : basic functionality ***
|
||||
bool(true)
|
||||
object(ArrayObject)#1 (1) {
|
||||
object(ArrayObject)#%d (1) {
|
||||
["storage":"ArrayObject":private]=>
|
||||
array(3) {
|
||||
[1]=>
|
||||
@ -33,8 +35,22 @@ object(ArrayObject)#1 (1) {
|
||||
int(4)
|
||||
}
|
||||
}
|
||||
|
||||
Warning: asort() expects parameter 2 to be long, string given in %sarrayObject_asort_basic1.php on line %d
|
||||
bool(false)
|
||||
object(ArrayObject)#%d (1) {
|
||||
["storage":"ArrayObject":private]=>
|
||||
array(3) {
|
||||
["a"]=>
|
||||
int(4)
|
||||
["b"]=>
|
||||
int(2)
|
||||
["c"]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
object(ArrayObject)#2 (1) {
|
||||
object(ArrayObject)#%d (1) {
|
||||
["storage":"ArrayObject":private]=>
|
||||
array(3) {
|
||||
["b"]=>
|
||||
|
@ -16,12 +16,14 @@ var_dump($ao1->ksort());
|
||||
var_dump($ao1);
|
||||
var_dump($ao2->ksort('blah'));
|
||||
var_dump($ao2);
|
||||
var_dump($ao2->ksort(SORT_STRING));
|
||||
var_dump($ao2);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
*** Testing ArrayObject::ksort() : basic functionality ***
|
||||
bool(true)
|
||||
object(ArrayObject)#1 (1) {
|
||||
object(ArrayObject)#%d (1) {
|
||||
["storage":"ArrayObject":private]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
@ -32,18 +34,34 @@ object(ArrayObject)#1 (1) {
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
|
||||
Warning: ksort() expects parameter 2 to be long, string given in %sarrayObject_ksort_basic1.php on line %d
|
||||
bool(false)
|
||||
object(ArrayObject)#2 (1) {
|
||||
["storage":"ArrayObject":private]=>
|
||||
array(4) {
|
||||
["a"]=>
|
||||
int(2)
|
||||
["b"]=>
|
||||
int(4)
|
||||
["a"]=>
|
||||
int(2)
|
||||
["q"]=>
|
||||
int(3)
|
||||
[99]=>
|
||||
string(1) "x"
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
object(ArrayObject)#%d (1) {
|
||||
["storage":"ArrayObject":private]=>
|
||||
array(4) {
|
||||
[99]=>
|
||||
string(1) "x"
|
||||
["a"]=>
|
||||
int(2)
|
||||
["b"]=>
|
||||
int(4)
|
||||
["q"]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
===DONE===
|
||||
|
19
ext/spl/tests/bug62904.phpt
Normal file
19
ext/spl/tests/bug62904.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Bug #62904 (Crash when cloning an object which inherits SplFixedArray)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class foo extends SplFixedArray {
|
||||
public function __construct($size) {
|
||||
}
|
||||
}
|
||||
|
||||
$x = new foo(2);
|
||||
|
||||
try {
|
||||
$z = clone $x;
|
||||
} catch (Exception $e) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
--EXPECTF--
|
||||
string(40) "The instance wasn't initialized properly"
|
@ -162,7 +162,10 @@ PHPAPI unsigned char *php_quot_print_encode(const unsigned char *str, size_t len
|
||||
lp = 0;
|
||||
} else {
|
||||
if (iscntrl (c) || (c == 0x7f) || (c & 0x80) || (c == '=') || ((c == ' ') && (*str == '\015'))) {
|
||||
if ((lp += 3) > PHP_QPRINT_MAXL) {
|
||||
if ((((lp+= 3) > PHP_QPRINT_MAXL) && (c <= 0x7f))
|
||||
|| ((c > 0x7f) && (c <= 0xdf) && ((lp + 3) > PHP_QPRINT_MAXL))
|
||||
|| ((c > 0xdf) && (c <= 0xef) && ((lp + 6) > PHP_QPRINT_MAXL))
|
||||
|| ((c > 0xef) && (c <= 0xf4) && ((lp + 9) > PHP_QPRINT_MAXL))) {
|
||||
*d++ = '=';
|
||||
*d++ = '\015';
|
||||
*d++ = '\012';
|
||||
@ -283,4 +286,4 @@ PHP_FUNCTION(quoted_printable_encode)
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
*/
|
17
ext/standard/tests/strings/bug62462.phpt
Normal file
17
ext/standard/tests/strings/bug62462.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Multibyte characters shouldn't be split by soft line break added by quoted_printable_encode - 4 byte character test
|
||||
--FILE--
|
||||
<?php
|
||||
echo quoted_printable_encode(str_repeat("\xc4\x85", 77));
|
||||
?>
|
||||
|
||||
==DONE==
|
||||
--EXPECT--
|
||||
=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=
|
||||
=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=
|
||||
=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=
|
||||
=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=
|
||||
=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=
|
||||
=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=C4=85=
|
||||
=C4=85=C4=85=C4=85=C4=85=C4=85
|
||||
==DONE==
|
Binary file not shown.
54
ext/zip/tests/bug51353.phpt
Normal file
54
ext/zip/tests/bug51353.phpt
Normal file
@ -0,0 +1,54 @@
|
||||
--TEST--
|
||||
Bug #51353 ZIP64 problem, archive with 100000 items
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if(!extension_loaded('zip')) die('skip');
|
||||
die('skip the test might get very long, activate it manually');
|
||||
--FILE--
|
||||
<?php
|
||||
/* This test might get very long depending on the mashine it's running on. Therefore
|
||||
adding an explicit skip, remove it to run this test. */
|
||||
set_time_limit(0);
|
||||
|
||||
$base_path = dirname(__FILE__);
|
||||
|
||||
/* Either we ship a file with 100000 entries which would be >12M big,
|
||||
or create it dynamically. */
|
||||
$zip = new ZipArchive;
|
||||
$r = $zip->open("$base_path/51353.zip", ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
|
||||
if ($r) {
|
||||
for ($i = 0; $i < 100000; $i++) {
|
||||
$zip->addFromString("$i.txt", '1');
|
||||
}
|
||||
$zip->close();
|
||||
} else {
|
||||
die("failed");
|
||||
}
|
||||
|
||||
$zip = new ZipArchive;
|
||||
$r = $zip->open("$base_path/51353.zip");
|
||||
if ($r) {
|
||||
$zip->extractTo("$base_path/51353_unpack");
|
||||
$zip->close();
|
||||
|
||||
$a = glob("$base_path/51353_unpack/*.txt");
|
||||
echo count($a) . "\n";
|
||||
} else {
|
||||
die("failed");
|
||||
}
|
||||
|
||||
echo "OK";
|
||||
--CLEAN--
|
||||
<?php
|
||||
$base_path = dirname(__FILE__);
|
||||
|
||||
unlink("$base_path/51353.zip");
|
||||
|
||||
$a = glob("$base_path/51353_unpack/*.txt");
|
||||
foreach($a as $f) {
|
||||
unlink($f);
|
||||
}
|
||||
rmdir("$base_path/51353_unpack");
|
||||
--EXPECT--
|
||||
100000
|
||||
OK
|
Loading…
Reference in New Issue
Block a user