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:
Nikita Popov 2012-08-24 13:29:40 +02:00
commit 6517ed0215
91 changed files with 1368 additions and 1560 deletions

202
INSTALL
View File

@ -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
View File

@ -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
View 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
View 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) {
}

View File

@ -1,5 +1,5 @@
--TEST--
Try catch finally
Try catch finally (basic test)
--FILE--
<?php
function foo ($throw = FALSE) {

View File

@ -1,5 +1,5 @@
--TEST--
Try catch finally return
Try catch finally (basic test with return)
--FILE--
<?php
function foo () {

View File

@ -1,5 +1,5 @@
--TEST--
Try catch finally multi-return
Try catch finally (with multi-returns)
--FILE--
<?php
function dummy($msg) {

View File

@ -1,5 +1,5 @@
--TEST--
Nesting try catch finally
Try catch finally (nesting try-catch-finally)
--FILE--
<?php

View File

@ -1,5 +1,5 @@
--TEST--
Try catch finally with return
Try catch finally (with multi-returns and exception)
--FILE--
<?php
function foo ($a) {

View File

@ -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) {

View 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"

View 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"

View 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"

View File

@ -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

View File

@ -1,5 +1,5 @@
--TEST--
Try finally
Try finally (re-throw exception in finally block)
--FILE--
<?php
function foo () {

View File

@ -1,5 +1,5 @@
--TEST--
Try finally
Try finally (call sequence test)
--FILE--
<?php
function foo () {

View File

@ -1,5 +1,5 @@
--TEST--
Try without catch/finally block
Try finally (without catch/finally block)
--FILE--
<?php
function foo () {

View File

@ -1,5 +1,5 @@
--TEST--
Finally with long goto
Try finally (with long goto)
--FILE--
<?php
function foo () {

View File

@ -1,5 +1,5 @@
--TEST--
Finally with near goto
Try finally (with near goto)
--FILE--
<?php
function foo () {

View File

@ -1,5 +1,5 @@
--TEST--
Finally with goto previous label
Try finally (with goto previous label)
--FILE--
<?php
function foo () {

View File

@ -1,5 +1,5 @@
--TEST--
Finally with jmp (do while)
Try finally (with break in do...while)
--FILE--
<?php
function foo () {

View File

@ -1,5 +1,5 @@
--TEST--
Finally with jmp (for continue)
Try finally (with for continue)
--FILE--
<?php
function foo () {

View File

@ -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

View File

@ -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[] = {

View File

@ -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));
}

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 ) \

View File

@ -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);

View File

@ -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"

View File

@ -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;
}

View File

@ -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

View File

@ -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,

View File

@ -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;
}

View File

@ -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

View File

@ -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) {

View File

@ -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) {

View File

@ -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;
}

View File

@ -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

View File

@ -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 );

View File

@ -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 );

View File

@ -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) \

View File

@ -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");

View File

@ -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 ==

View File

@ -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 ==

View File

@ -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 ==

View File

@ -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 ==

View File

@ -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 ==

View File

@ -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 ==

View File

@ -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 ==

View 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"

View 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"

View 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"

View File

@ -2,7 +2,6 @@
LOAD DATA INFILE - open_basedir
--SKIPIF--
<?php
@include_once("connect.inc");
include_once('skipif.inc');
include_once('skipifconnectfailure.inc');

View File

@ -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);
}

View 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

View File

@ -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 {

View File

@ -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();
?>

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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++;
}
}

View File

@ -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 */

View File

@ -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) {

View File

@ -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"]=>

View File

@ -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===

View 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"

View File

@ -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
*/
*/

View 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==

View 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