1999-04-08 02:10:10 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2014-01-03 11:08:10 +08:00
| Copyright ( c ) 1998 - 2014 Zend Technologies Ltd . ( http : //www.zend.com) |
1999-04-08 02:10:10 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-12-11 23:16:21 +08:00
| This source file is subject to version 2.00 of the Zend license , |
2006-05-13 18:37:45 +08:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-11 04:04:29 +08:00
| available through the world - wide - web at the following url : |
2001-12-11 23:16:21 +08:00
| http : //www.zend.com/license/2_00.txt. |
1999-07-16 22:58:16 +08:00
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ zend . com so we can mail you a copy immediately . |
1999-04-08 02:10:10 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Andi Gutmans < andi @ zend . com > |
| Zeev Suraski < zeev @ zend . com > |
2001-07-10 02:51:29 +08:00
| Andrei Zmievski < andrei @ php . net > |
1999-04-08 02:10:10 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2003-02-01 09:49:15 +08:00
/* $Id$ */
1999-07-16 22:58:16 +08:00
1999-04-08 02:10:10 +08:00
# include "zend.h"
# include "zend_execute.h"
# include "zend_API.h"
2001-02-27 02:18:34 +08:00
# include "zend_modules.h"
1999-04-08 02:10:10 +08:00
# include "zend_constants.h"
2008-02-02 05:27:55 +08:00
# include "zend_exceptions.h"
2008-07-14 17:49:03 +08:00
# include "zend_closures.h"
1999-04-08 02:10:10 +08:00
1999-09-07 00:14:08 +08:00
# ifdef HAVE_STDARG_H
2000-06-06 10:47:43 +08:00
# include <stdarg.h>
1999-04-08 02:10:10 +08:00
# endif
/* these variables are true statics/globals, and have to be mutex'ed on every access */
2000-10-27 07:50:17 +08:00
ZEND_API HashTable module_registry ;
1999-04-08 02:10:10 +08:00
2010-07-06 19:40:17 +08:00
static zend_module_entry * * module_request_startup_handlers ;
static zend_module_entry * * module_request_shutdown_handlers ;
static zend_module_entry * * module_post_deactivate_handlers ;
static zend_class_entry * * class_cleanup_handlers ;
1999-04-08 02:10:10 +08:00
/* this function doesn't check for too many parameters */
2007-11-03 03:40:39 +08:00
ZEND_API int zend_get_parameters ( int ht , int param_count , . . . ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-04-21 11:49:09 +08:00
int arg_count ;
1999-04-08 02:10:10 +08:00
va_list ptr ;
1999-04-13 02:29:09 +08:00
zval * * param , * param_ptr ;
2001-07-27 18:10:39 +08:00
TSRMLS_FETCH ( ) ;
1999-04-21 11:49:09 +08:00
2014-07-03 02:01:25 +08:00
param_ptr = ZEND_CALL_ARG ( EG ( current_execute_data ) , 1 ) ;
arg_count = EG ( current_execute_data ) - > num_args ;
1999-04-13 02:29:09 +08:00
if ( param_count > arg_count ) {
return FAILURE ;
}
1999-04-08 02:10:10 +08:00
va_start ( ptr , param_count ) ;
2000-06-10 09:08:55 +08:00
while ( param_count - - > 0 ) {
1999-04-08 02:10:10 +08:00
param = va_arg ( ptr , zval * * ) ;
2014-02-10 14:04:30 +08:00
if ( ! Z_ISREF_P ( param_ptr ) & & Z_REFCOUNT_P ( param_ptr ) > 1 ) {
zval new_tmp ;
ZVAL_DUP ( & new_tmp , param_ptr ) ;
Z_DELREF_P ( param_ptr ) ;
ZVAL_COPY_VALUE ( param_ptr , & new_tmp ) ;
1999-04-08 02:10:10 +08:00
}
* param = param_ptr ;
2014-06-24 06:17:16 +08:00
param_ptr + + ;
1999-04-13 03:44:47 +08:00
}
1999-04-08 02:10:10 +08:00
va_end ( ptr ) ;
1999-04-13 02:29:09 +08:00
1999-04-08 02:10:10 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
1999-04-15 03:53:33 +08:00
/* Zend-optimized Extended functions */
/* this function doesn't check for too many parameters */
2007-11-03 03:40:39 +08:00
ZEND_API int zend_get_parameters_ex ( int param_count , . . . ) /* { { { */
1999-04-15 03:53:33 +08:00
{
1999-04-21 11:49:09 +08:00
int arg_count ;
1999-04-15 03:53:33 +08:00
va_list ptr ;
2014-06-24 06:17:16 +08:00
zval * * param , * param_ptr ;
2001-07-27 18:10:39 +08:00
TSRMLS_FETCH ( ) ;
1999-04-15 03:53:33 +08:00
2014-07-03 02:01:25 +08:00
param_ptr = ZEND_CALL_ARG ( EG ( current_execute_data ) , 1 ) ;
arg_count = EG ( current_execute_data ) - > num_args ;
1999-04-21 11:49:09 +08:00
1999-04-15 03:53:33 +08:00
if ( param_count > arg_count ) {
return FAILURE ;
}
va_start ( ptr , param_count ) ;
2000-06-10 09:08:55 +08:00
while ( param_count - - > 0 ) {
2014-02-10 14:04:30 +08:00
param = va_arg ( ptr , zval * * ) ;
2014-06-24 06:17:16 +08:00
* param = param_ptr ;
param_ptr + + ;
1999-04-15 03:53:33 +08:00
}
va_end ( ptr ) ;
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-15 03:53:33 +08:00
2014-02-10 14:04:30 +08:00
ZEND_API int _zend_get_parameters_array_ex ( int param_count , zval * argument_array TSRMLS_DC ) /* { { { */
1999-04-15 03:53:33 +08:00
{
2014-06-24 06:17:16 +08:00
zval * param_ptr ;
1999-04-21 11:49:09 +08:00
int arg_count ;
1999-04-15 03:53:33 +08:00
2014-07-03 02:01:25 +08:00
param_ptr = ZEND_CALL_ARG ( EG ( current_execute_data ) , 1 ) ;
arg_count = EG ( current_execute_data ) - > num_args ;
1999-04-21 11:49:09 +08:00
1999-04-15 03:53:33 +08:00
if ( param_count > arg_count ) {
return FAILURE ;
}
2000-06-10 09:08:55 +08:00
while ( param_count - - > 0 ) {
2014-06-24 06:17:16 +08:00
ZVAL_COPY_VALUE ( argument_array , param_ptr ) ;
2014-02-10 14:04:30 +08:00
argument_array + + ;
2014-06-24 06:17:16 +08:00
param_ptr + + ;
1999-04-15 03:53:33 +08:00
}
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-15 03:53:33 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int zend_copy_parameters_array ( int param_count , zval * argument_array TSRMLS_DC ) /* { { { */
2004-09-29 06:55:22 +08:00
{
2014-06-24 06:17:16 +08:00
zval * param_ptr ;
2004-09-29 06:55:22 +08:00
int arg_count ;
2014-07-03 02:01:25 +08:00
param_ptr = ZEND_CALL_ARG ( EG ( current_execute_data ) , 1 ) ;
arg_count = EG ( current_execute_data ) - > num_args ;
2004-09-29 06:55:22 +08:00
if ( param_count > arg_count ) {
return FAILURE ;
}
while ( param_count - - > 0 ) {
2014-06-24 06:17:16 +08:00
if ( Z_REFCOUNTED_P ( param_ptr ) ) {
Z_ADDREF_P ( param_ptr ) ;
2014-02-21 21:12:12 +08:00
}
2014-06-27 03:51:14 +08:00
zend_hash_next_index_insert_new ( Z_ARRVAL_P ( argument_array ) , param_ptr ) ;
2014-06-24 06:17:16 +08:00
param_ptr + + ;
2004-09-29 06:55:22 +08:00
}
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2004-09-29 06:55:22 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API void zend_wrong_param_count ( TSRMLS_D ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2011-09-13 21:29:35 +08:00
const char * space ;
const char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
2007-11-03 03:40:39 +08:00
2005-06-17 19:25:31 +08:00
zend_error ( E_WARNING , " Wrong parameter count for %s%s%s() " , class_name , space , get_active_function_name ( TSRMLS_C ) ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
/* Argument parsing API -- andrei */
2007-11-03 03:40:39 +08:00
ZEND_API char * zend_get_type_by_const ( int type ) /* { { { */
2001-07-10 02:51:29 +08:00
{
2006-05-25 18:01:06 +08:00
switch ( type ) {
2014-04-30 22:32:42 +08:00
case IS_FALSE :
case IS_TRUE :
2006-05-25 18:01:06 +08:00
return " boolean " ;
2014-08-26 01:24:55 +08:00
case IS_LONG :
2001-07-10 02:51:29 +08:00
return " integer " ;
case IS_DOUBLE :
return " double " ;
case IS_STRING :
return " string " ;
case IS_OBJECT :
return " object " ;
case IS_RESOURCE :
return " resource " ;
2006-05-25 18:01:06 +08:00
case IS_NULL :
return " null " ;
2011-08-16 18:44:47 +08:00
case IS_CALLABLE :
return " callable " ;
2006-05-25 18:01:06 +08:00
case IS_ARRAY :
return " array " ;
2001-07-10 02:51:29 +08:00
default :
return " unknown " ;
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API char * zend_zval_type_name ( const zval * arg ) /* { { { */
2006-05-25 18:01:06 +08:00
{
2014-03-27 17:39:09 +08:00
ZVAL_DEREF ( arg ) ;
2006-05-25 18:01:06 +08:00
return zend_get_type_by_const ( Z_TYPE_P ( arg ) ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2006-05-25 18:01:06 +08:00
2014-03-28 06:11:22 +08:00
ZEND_API zend_class_entry * zend_get_class_entry ( const zend_object * zobject TSRMLS_DC ) /* { { { */
2002-04-22 22:22:27 +08:00
{
2014-03-28 06:11:22 +08:00
if ( zobject - > handlers - > get_class_entry ) {
return zobject - > handlers - > get_class_entry ( zobject TSRMLS_CC ) ;
2002-04-22 22:22:27 +08:00
} else {
2002-04-30 17:56:48 +08:00
zend_error ( E_ERROR , " Class entry requested for an object without PHP class " ) ;
return NULL ;
2002-04-22 22:22:27 +08:00
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2002-04-22 22:22:27 +08:00
2005-06-29 16:43:38 +08:00
/* returns 1 if you need to copy result, 0 if it's already a copy */
2014-03-28 06:11:22 +08:00
ZEND_API zend_string * zend_get_object_classname ( const zend_object * object TSRMLS_DC ) /* { { { */
2005-06-28 02:13:13 +08:00
{
2014-02-10 14:04:30 +08:00
zend_string * ret ;
2006-05-10 07:53:23 +08:00
2014-03-28 06:11:22 +08:00
if ( object - > handlers - > get_class_name ! = NULL ) {
ret = object - > handlers - > get_class_name ( object , 0 TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
if ( ret ) {
return ret ;
}
2005-06-28 02:13:13 +08:00
}
2014-03-28 06:11:22 +08:00
return zend_get_class_entry ( object TSRMLS_CC ) - > name ;
2005-06-28 02:13:13 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-06-28 02:13:13 +08:00
2014-08-27 21:31:48 +08:00
static int parse_arg_object_to_string ( zval * arg , char * * p , size_t * pl , int type TSRMLS_DC ) /* { { { */
2006-05-13 18:37:45 +08:00
{
2014-02-10 14:04:30 +08:00
if ( Z_OBJ_HANDLER_P ( arg , cast_object ) ) {
zval obj ;
if ( Z_OBJ_HANDLER_P ( arg , cast_object ) ( arg , & obj , type TSRMLS_CC ) = = SUCCESS ) {
2012-03-02 10:51:57 +08:00
zval_ptr_dtor ( arg ) ;
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( arg , & obj ) ;
2014-08-26 01:24:55 +08:00
* pl = Z_STRLEN_P ( arg ) ;
2014-02-10 14:04:30 +08:00
* p = Z_STRVAL_P ( arg ) ;
2006-05-13 18:37:45 +08:00
return SUCCESS ;
}
}
/* Standard PHP objects */
2014-02-10 14:04:30 +08:00
if ( Z_OBJ_HT_P ( arg ) = = & std_object_handlers | | ! Z_OBJ_HANDLER_P ( arg , cast_object ) ) {
2014-06-05 20:04:11 +08:00
SEPARATE_ZVAL_NOREF ( arg ) ;
2014-02-10 14:04:30 +08:00
if ( zend_std_cast_object_tostring ( arg , arg , type TSRMLS_CC ) = = SUCCESS ) {
2014-08-26 01:24:55 +08:00
* pl = Z_STRLEN_P ( arg ) ;
2014-02-10 14:04:30 +08:00
* p = Z_STRVAL_P ( arg ) ;
2006-05-13 18:37:45 +08:00
return SUCCESS ;
}
}
2014-02-10 14:04:30 +08:00
if ( ! Z_OBJ_HANDLER_P ( arg , cast_object ) & & Z_OBJ_HANDLER_P ( arg , get ) ) {
2014-04-15 11:05:03 +08:00
zval rv ;
zval * z = Z_OBJ_HANDLER_P ( arg , get ) ( arg , & rv TSRMLS_CC ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( z ) ;
2006-05-13 18:37:45 +08:00
if ( Z_TYPE_P ( z ) ! = IS_OBJECT ) {
2014-02-10 14:04:30 +08:00
zval_dtor ( arg ) ;
2014-04-03 19:26:23 +08:00
ZVAL_NULL ( arg ) ;
2014-08-11 13:09:46 +08:00
if ( ! zend_make_printable_zval ( z , arg TSRMLS_CC ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_ZVAL ( arg , z , 1 , 1 ) ;
2006-05-13 18:37:45 +08:00
}
2014-08-26 01:24:55 +08:00
* pl = Z_STRLEN_P ( arg ) ;
2014-02-10 14:04:30 +08:00
* p = Z_STRVAL_P ( arg ) ;
2006-05-13 18:37:45 +08:00
return SUCCESS ;
}
2014-02-10 14:04:30 +08:00
zval_ptr_dtor ( z ) ;
2006-05-13 18:37:45 +08:00
}
return FAILURE ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2014-07-11 20:32:20 +08:00
ZEND_API int parse_arg_object_to_str ( zval * arg , zend_string * * str , int type TSRMLS_DC ) /* { { { */
2014-02-24 15:03:35 +08:00
{
if ( Z_OBJ_HANDLER_P ( arg , cast_object ) ) {
zval obj ;
if ( Z_OBJ_HANDLER_P ( arg , cast_object ) ( arg , & obj , type TSRMLS_CC ) = = SUCCESS ) {
zval_ptr_dtor ( arg ) ;
ZVAL_COPY_VALUE ( arg , & obj ) ;
* str = Z_STR_P ( arg ) ;
return SUCCESS ;
}
}
/* Standard PHP objects */
if ( Z_OBJ_HT_P ( arg ) = = & std_object_handlers | | ! Z_OBJ_HANDLER_P ( arg , cast_object ) ) {
2014-06-05 20:04:11 +08:00
SEPARATE_ZVAL_NOREF ( arg ) ;
2014-02-24 15:03:35 +08:00
if ( zend_std_cast_object_tostring ( arg , arg , type TSRMLS_CC ) = = SUCCESS ) {
* str = Z_STR_P ( arg ) ;
return SUCCESS ;
}
}
if ( ! Z_OBJ_HANDLER_P ( arg , cast_object ) & & Z_OBJ_HANDLER_P ( arg , get ) ) {
2014-04-15 11:05:03 +08:00
zval rv ;
zval * z = Z_OBJ_HANDLER_P ( arg , get ) ( arg , & rv TSRMLS_CC ) ;
2014-02-24 15:03:35 +08:00
Z_ADDREF_P ( z ) ;
if ( Z_TYPE_P ( z ) ! = IS_OBJECT ) {
zval_dtor ( arg ) ;
2014-04-03 19:26:23 +08:00
ZVAL_NULL ( arg ) ;
2014-08-11 13:09:46 +08:00
if ( ! zend_make_printable_zval ( z , arg TSRMLS_CC ) ) {
2014-02-24 15:03:35 +08:00
ZVAL_ZVAL ( arg , z , 1 , 1 ) ;
}
* str = Z_STR_P ( arg ) ;
return SUCCESS ;
}
zval_ptr_dtor ( z ) ;
}
return FAILURE ;
}
/* }}} */
2014-07-11 20:32:20 +08:00
# ifdef FAST_ZPP
ZEND_API void zend_wrong_paramers_count_error ( int num_args , int min_num_args , int max_num_args TSRMLS_DC ) /* { { { */
{
zend_function * active_function = EG ( current_execute_data ) - > func ;
const char * class_name = active_function - > common . scope ? active_function - > common . scope - > name - > val : " " ;
zend_error ( E_WARNING , " %s%s%s() expects %s %d parameter%s, %d given " ,
class_name , \
class_name [ 0 ] ? " :: " : " " , \
active_function - > common . function_name - > val ,
min_num_args = = max_num_args ? " exactly " : num_args < min_num_args ? " at least " : " at most " ,
num_args < min_num_args ? min_num_args : max_num_args ,
( num_args < min_num_args ? min_num_args : max_num_args ) = = 1 ? " " : " s " ,
num_args ) ;
}
/* }}} */
ZEND_API void zend_wrong_paramer_type_error ( int num , zend_expected_type expected_type , zval * arg TSRMLS_DC ) /* { { { */
{
const char * space ;
const char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
static const char * const expected_error [ ] = {
Z_EXPECTED_TYPES ( Z_EXPECTED_TYPE_STR )
NULL
} ;
zend_error ( E_WARNING , " %s%s%s() expects parameter %d to be %s, %s given " ,
class_name , space , get_active_function_name ( TSRMLS_C ) , num , expected_error [ expected_type ] , zend_zval_type_name ( arg ) ) ;
}
/* }}} */
ZEND_API void zend_wrong_paramer_class_error ( int num , char * name , zval * arg TSRMLS_DC ) /* { { { */
{
const char * space ;
const char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
zend_error ( E_WARNING , " %s%s%s() expects parameter %d to be %s, %s given " ,
class_name , space , get_active_function_name ( TSRMLS_C ) , num , name , zend_zval_type_name ( arg ) ) ;
}
/* }}} */
ZEND_API void zend_wrong_callback_error ( int severity , int num , char * error TSRMLS_DC ) /* { { { */
{
const char * space ;
const char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
zend_error ( severity , " %s%s%s() expects parameter %d to be a valid callback, %s " ,
class_name , space , get_active_function_name ( TSRMLS_C ) , num , error ) ;
efree ( error ) ;
}
/* }}} */
2014-07-14 18:25:04 +08:00
ZEND_API int _z_param_class ( zval * arg , zend_class_entry * * pce , int num , int check_null TSRMLS_DC ) /* { { { */
2014-07-11 20:32:20 +08:00
{
zend_class_entry * ce_base = * pce ;
if ( check_null & & Z_TYPE_P ( arg ) = = IS_NULL ) {
* pce = NULL ;
return 1 ;
}
convert_to_string_ex ( arg ) ;
* pce = zend_lookup_class ( Z_STR_P ( arg ) TSRMLS_CC ) ;
if ( ce_base ) {
if ( ( ! * pce | | ! instanceof_function ( * pce , ce_base TSRMLS_CC ) ) ) {
const char * space ;
const char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
zend_error ( E_WARNING , " %s%s%s() expects parameter %d to be a class name derived from %s, '%s' given " ,
class_name , space , get_active_function_name ( TSRMLS_C ) , num ,
ce_base - > name - > val , Z_STRVAL_P ( arg ) ) ;
* pce = NULL ;
return 0 ;
}
}
if ( ! * pce ) {
const char * space ;
const char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
zend_error ( E_WARNING , " %s%s%s() expects parameter %d to be a valid class name, '%s' given " ,
class_name , space , get_active_function_name ( TSRMLS_C ) , num ,
Z_STRVAL_P ( arg ) ) ;
return 0 ;
}
return 1 ;
}
/* }}} */
# endif
2014-02-10 14:04:30 +08:00
static const char * zend_parse_arg_impl ( int arg_num , zval * arg , va_list * va , const char * * spec , char * * error , int * severity TSRMLS_DC ) /* { { { */
2001-07-10 02:51:29 +08:00
{
2010-10-15 05:33:10 +08:00
const char * spec_walk = * spec ;
2001-07-10 02:51:29 +08:00
char c = * spec_walk + + ;
zend_parse_parameters: allow ! for non pointers
This commit allows getting information about whether a certain value
was a NULL value by using the ! modifier together with the l/L, d and
b.
Example:
long l;
zend_bool is_null;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &l, &is_null)
For the specifiers l/L, d and b, NULL values are reported as 0, 0., or
false. But sometimes one wants to distinguish NULL from those other
values -- for instance, to give NULL the same effect as the argument
not having been passed.
The usual way this problem is handled is by fetching the parameter
with 'z' or 'Z', check if it is NULL and if not use
convert_to_long_ex()/convert_to_double_ex(), etc. Unfortunately, this
is not equivalent. convert_to_long_ex() does a cast, while zpp() is
stricter. For instance, zpp will not accept 'foo' for a long argument,
and it will emit a notice when encountering '5foo'.
In fact, the only way to otherwise zpp semantics (without duplicating
its logic) is to fetch the raw zval from the stack and check whether
it's NULL (with zpp itself or its relatives) and then run zpp again.
That is not an elegant solution.
2012-07-19 03:42:36 +08:00
int check_null = 0 ;
2014-02-19 18:35:28 +08:00
zval * real_arg = arg ;
2001-07-10 02:51:29 +08:00
2007-11-03 03:40:39 +08:00
/* scan through modifiers */
2014-06-05 20:04:11 +08:00
ZVAL_DEREF ( arg ) ;
2007-11-03 03:40:39 +08:00
while ( 1 ) {
2001-07-10 02:51:29 +08:00
if ( * spec_walk = = ' / ' ) {
2014-06-05 20:04:11 +08:00
SEPARATE_ZVAL ( arg ) ;
real_arg = arg ;
2007-11-03 03:40:39 +08:00
} else if ( * spec_walk = = ' ! ' ) {
zend_parse_parameters: allow ! for non pointers
This commit allows getting information about whether a certain value
was a NULL value by using the ! modifier together with the l/L, d and
b.
Example:
long l;
zend_bool is_null;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &l, &is_null)
For the specifiers l/L, d and b, NULL values are reported as 0, 0., or
false. But sometimes one wants to distinguish NULL from those other
values -- for instance, to give NULL the same effect as the argument
not having been passed.
The usual way this problem is handled is by fetching the parameter
with 'z' or 'Z', check if it is NULL and if not use
convert_to_long_ex()/convert_to_double_ex(), etc. Unfortunately, this
is not equivalent. convert_to_long_ex() does a cast, while zpp() is
stricter. For instance, zpp will not accept 'foo' for a long argument,
and it will emit a notice when encountering '5foo'.
In fact, the only way to otherwise zpp semantics (without duplicating
its logic) is to fetch the raw zval from the stack and check whether
it's NULL (with zpp itself or its relatives) and then run zpp again.
That is not an elegant solution.
2012-07-19 03:42:36 +08:00
check_null = 1 ;
2007-11-03 03:40:39 +08:00
} else {
break ;
2001-07-10 02:51:29 +08:00
}
spec_walk + + ;
}
switch ( c ) {
case ' l ' :
2009-06-05 02:20:45 +08:00
case ' L ' :
2001-07-10 02:51:29 +08:00
{
2014-08-26 01:24:55 +08:00
zend_long * p = va_arg ( * va , zend_long * ) ;
zend_parse_parameters: allow ! for non pointers
This commit allows getting information about whether a certain value
was a NULL value by using the ! modifier together with the l/L, d and
b.
Example:
long l;
zend_bool is_null;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &l, &is_null)
For the specifiers l/L, d and b, NULL values are reported as 0, 0., or
false. But sometimes one wants to distinguish NULL from those other
values -- for instance, to give NULL the same effect as the argument
not having been passed.
The usual way this problem is handled is by fetching the parameter
with 'z' or 'Z', check if it is NULL and if not use
convert_to_long_ex()/convert_to_double_ex(), etc. Unfortunately, this
is not equivalent. convert_to_long_ex() does a cast, while zpp() is
stricter. For instance, zpp will not accept 'foo' for a long argument,
and it will emit a notice when encountering '5foo'.
In fact, the only way to otherwise zpp semantics (without duplicating
its logic) is to fetch the raw zval from the stack and check whether
it's NULL (with zpp itself or its relatives) and then run zpp again.
That is not an elegant solution.
2012-07-19 03:42:36 +08:00
if ( check_null ) {
zend_bool * p = va_arg ( * va , zend_bool * ) ;
2014-02-10 14:04:30 +08:00
* p = ( Z_TYPE_P ( arg ) = = IS_NULL ) ;
zend_parse_parameters: allow ! for non pointers
This commit allows getting information about whether a certain value
was a NULL value by using the ! modifier together with the l/L, d and
b.
Example:
long l;
zend_bool is_null;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &l, &is_null)
For the specifiers l/L, d and b, NULL values are reported as 0, 0., or
false. But sometimes one wants to distinguish NULL from those other
values -- for instance, to give NULL the same effect as the argument
not having been passed.
The usual way this problem is handled is by fetching the parameter
with 'z' or 'Z', check if it is NULL and if not use
convert_to_long_ex()/convert_to_double_ex(), etc. Unfortunately, this
is not equivalent. convert_to_long_ex() does a cast, while zpp() is
stricter. For instance, zpp will not accept 'foo' for a long argument,
and it will emit a notice when encountering '5foo'.
In fact, the only way to otherwise zpp semantics (without duplicating
its logic) is to fetch the raw zval from the stack and check whether
it's NULL (with zpp itself or its relatives) and then run zpp again.
That is not an elegant solution.
2012-07-19 03:42:36 +08:00
}
2014-02-10 14:04:30 +08:00
switch ( Z_TYPE_P ( arg ) ) {
2001-07-10 02:51:29 +08:00
case IS_STRING :
{
double d ;
int type ;
2014-08-26 01:24:55 +08:00
if ( ( type = is_numeric_string ( Z_STRVAL_P ( arg ) , Z_STRLEN_P ( arg ) , p , & d , - 1 ) ) = = 0 ) {
2001-07-10 02:51:29 +08:00
return " long " ;
} else if ( type = = IS_DOUBLE ) {
2009-06-05 02:20:45 +08:00
if ( c = = ' L ' ) {
2014-08-26 02:22:49 +08:00
if ( d > ZEND_LONG_MAX ) {
* p = ZEND_LONG_MAX ;
2014-08-16 17:16:11 +08:00
break ;
2014-08-26 02:22:49 +08:00
} else if ( d < ZEND_LONG_MIN ) {
* p = ZEND_LONG_MIN ;
2014-08-16 17:16:11 +08:00
break ;
}
}
2014-08-26 01:24:55 +08:00
* p = zend_dval_to_lval ( d ) ;
2014-08-16 17:16:11 +08:00
}
}
break ;
case IS_DOUBLE :
2014-08-26 01:24:55 +08:00
if ( c = = ' L ' ) {
2014-08-26 02:22:49 +08:00
if ( Z_DVAL_P ( arg ) > ZEND_LONG_MAX ) {
* p = ZEND_LONG_MAX ;
2014-08-16 17:16:11 +08:00
break ;
2014-08-26 02:22:49 +08:00
} else if ( Z_DVAL_P ( arg ) < ZEND_LONG_MIN ) {
* p = ZEND_LONG_MIN ;
2014-08-16 17:16:11 +08:00
break ;
}
}
case IS_NULL :
case IS_FALSE :
case IS_TRUE :
2014-08-26 01:24:55 +08:00
case IS_LONG :
2014-08-26 03:51:49 +08:00
convert_to_long_ex ( arg ) ;
2014-08-26 01:24:55 +08:00
* p = Z_LVAL_P ( arg ) ;
2001-07-10 02:51:29 +08:00
break ;
case IS_ARRAY :
case IS_OBJECT :
case IS_RESOURCE :
default :
return " long " ;
}
}
break ;
case ' d ' :
{
double * p = va_arg ( * va , double * ) ;
zend_parse_parameters: allow ! for non pointers
This commit allows getting information about whether a certain value
was a NULL value by using the ! modifier together with the l/L, d and
b.
Example:
long l;
zend_bool is_null;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &l, &is_null)
For the specifiers l/L, d and b, NULL values are reported as 0, 0., or
false. But sometimes one wants to distinguish NULL from those other
values -- for instance, to give NULL the same effect as the argument
not having been passed.
The usual way this problem is handled is by fetching the parameter
with 'z' or 'Z', check if it is NULL and if not use
convert_to_long_ex()/convert_to_double_ex(), etc. Unfortunately, this
is not equivalent. convert_to_long_ex() does a cast, while zpp() is
stricter. For instance, zpp will not accept 'foo' for a long argument,
and it will emit a notice when encountering '5foo'.
In fact, the only way to otherwise zpp semantics (without duplicating
its logic) is to fetch the raw zval from the stack and check whether
it's NULL (with zpp itself or its relatives) and then run zpp again.
That is not an elegant solution.
2012-07-19 03:42:36 +08:00
if ( check_null ) {
zend_bool * p = va_arg ( * va , zend_bool * ) ;
2014-02-10 14:04:30 +08:00
* p = ( Z_TYPE_P ( arg ) = = IS_NULL ) ;
zend_parse_parameters: allow ! for non pointers
This commit allows getting information about whether a certain value
was a NULL value by using the ! modifier together with the l/L, d and
b.
Example:
long l;
zend_bool is_null;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &l, &is_null)
For the specifiers l/L, d and b, NULL values are reported as 0, 0., or
false. But sometimes one wants to distinguish NULL from those other
values -- for instance, to give NULL the same effect as the argument
not having been passed.
The usual way this problem is handled is by fetching the parameter
with 'z' or 'Z', check if it is NULL and if not use
convert_to_long_ex()/convert_to_double_ex(), etc. Unfortunately, this
is not equivalent. convert_to_long_ex() does a cast, while zpp() is
stricter. For instance, zpp will not accept 'foo' for a long argument,
and it will emit a notice when encountering '5foo'.
In fact, the only way to otherwise zpp semantics (without duplicating
its logic) is to fetch the raw zval from the stack and check whether
it's NULL (with zpp itself or its relatives) and then run zpp again.
That is not an elegant solution.
2012-07-19 03:42:36 +08:00
}
2014-02-10 14:04:30 +08:00
switch ( Z_TYPE_P ( arg ) ) {
2001-07-10 02:51:29 +08:00
case IS_STRING :
{
2014-08-26 01:24:55 +08:00
zend_long l ;
2001-07-10 02:51:29 +08:00
int type ;
2014-08-26 01:24:55 +08:00
if ( ( type = is_numeric_string ( Z_STRVAL_P ( arg ) , Z_STRLEN_P ( arg ) , & l , p , - 1 ) ) = = 0 ) {
2001-07-10 02:51:29 +08:00
return " double " ;
2014-08-26 01:24:55 +08:00
} else if ( type = = IS_LONG ) {
2001-07-10 02:51:29 +08:00
* p = ( double ) l ;
}
}
break ;
case IS_NULL :
2014-04-30 22:32:42 +08:00
case IS_FALSE :
case IS_TRUE :
2014-08-26 01:24:55 +08:00
case IS_LONG :
2001-07-10 02:51:29 +08:00
case IS_DOUBLE :
convert_to_double_ex ( arg ) ;
2014-02-10 14:04:30 +08:00
* p = Z_DVAL_P ( arg ) ;
2001-07-10 02:51:29 +08:00
break ;
case IS_ARRAY :
case IS_OBJECT :
case IS_RESOURCE :
default :
return " double " ;
}
}
break ;
2011-06-07 05:28:16 +08:00
case ' p ' :
2001-07-10 02:51:29 +08:00
case ' s ' :
{
char * * p = va_arg ( * va , char * * ) ;
2014-08-27 21:31:48 +08:00
size_t * pl = va_arg ( * va , size_t * ) ;
2014-02-10 14:04:30 +08:00
switch ( Z_TYPE_P ( arg ) ) {
2001-07-10 02:51:29 +08:00
case IS_NULL :
zend_parse_parameters: allow ! for non pointers
This commit allows getting information about whether a certain value
was a NULL value by using the ! modifier together with the l/L, d and
b.
Example:
long l;
zend_bool is_null;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &l, &is_null)
For the specifiers l/L, d and b, NULL values are reported as 0, 0., or
false. But sometimes one wants to distinguish NULL from those other
values -- for instance, to give NULL the same effect as the argument
not having been passed.
The usual way this problem is handled is by fetching the parameter
with 'z' or 'Z', check if it is NULL and if not use
convert_to_long_ex()/convert_to_double_ex(), etc. Unfortunately, this
is not equivalent. convert_to_long_ex() does a cast, while zpp() is
stricter. For instance, zpp will not accept 'foo' for a long argument,
and it will emit a notice when encountering '5foo'.
In fact, the only way to otherwise zpp semantics (without duplicating
its logic) is to fetch the raw zval from the stack and check whether
it's NULL (with zpp itself or its relatives) and then run zpp again.
That is not an elegant solution.
2012-07-19 03:42:36 +08:00
if ( check_null ) {
2001-07-10 02:51:29 +08:00
* p = NULL ;
* pl = 0 ;
break ;
}
/* break omitted intentionally */
2014-08-26 01:24:55 +08:00
case IS_LONG :
2001-07-10 02:51:29 +08:00
case IS_DOUBLE :
2014-04-30 22:32:42 +08:00
case IS_FALSE :
case IS_TRUE :
2001-07-10 02:51:29 +08:00
convert_to_string_ex ( arg ) ;
2014-05-13 14:05:28 +08:00
case IS_STRING :
2014-02-10 14:04:30 +08:00
* p = Z_STRVAL_P ( arg ) ;
2014-08-26 01:24:55 +08:00
* pl = Z_STRLEN_P ( arg ) ;
2014-02-10 14:04:30 +08:00
if ( c = = ' p ' & & CHECK_ZVAL_NULL_PATH ( arg ) ) {
2011-06-08 08:53:55 +08:00
return " a valid path " ;
2011-06-07 05:28:16 +08:00
}
2001-07-10 02:51:29 +08:00
break ;
2006-05-10 07:53:23 +08:00
2006-05-13 18:37:45 +08:00
case IS_OBJECT :
if ( parse_arg_object_to_string ( arg , p , pl , IS_STRING TSRMLS_CC ) = = SUCCESS ) {
2014-02-10 14:04:30 +08:00
if ( c = = ' p ' & & CHECK_ZVAL_NULL_PATH ( arg ) ) {
2011-06-08 08:53:55 +08:00
return " a valid path " ;
2011-06-07 05:28:16 +08:00
}
2006-05-13 18:37:45 +08:00
break ;
2006-05-12 08:21:00 +08:00
}
2006-05-10 07:53:23 +08:00
2001-07-10 02:51:29 +08:00
case IS_ARRAY :
case IS_RESOURCE :
default :
2011-06-09 08:23:43 +08:00
return c = = ' s ' ? " string " : " a valid path " ;
2001-07-10 02:51:29 +08:00
}
}
break ;
2014-05-05 10:49:27 +08:00
case ' P ' :
2014-02-10 14:04:30 +08:00
case ' S ' :
{
zend_string * * str = va_arg ( * va , zend_string * * ) ;
switch ( Z_TYPE_P ( arg ) ) {
case IS_NULL :
if ( check_null ) {
* str = NULL ;
break ;
}
/* break omitted intentionally */
2014-08-26 01:24:55 +08:00
case IS_LONG :
2014-02-10 14:04:30 +08:00
case IS_DOUBLE :
2014-04-30 22:32:42 +08:00
case IS_FALSE :
case IS_TRUE :
2014-02-10 14:04:30 +08:00
convert_to_string_ex ( arg ) ;
2014-05-13 14:05:28 +08:00
case IS_STRING :
2014-02-10 14:04:30 +08:00
* str = Z_STR_P ( arg ) ;
2014-05-05 10:49:27 +08:00
if ( c = = ' P ' & & CHECK_ZVAL_NULL_PATH ( arg ) ) {
return " a valid path " ;
}
2014-02-10 14:04:30 +08:00
break ;
case IS_OBJECT : {
2014-02-24 15:03:35 +08:00
if ( parse_arg_object_to_str ( arg , str , IS_STRING TSRMLS_CC ) = = SUCCESS ) {
2014-05-05 10:49:27 +08:00
if ( c = = ' P ' & & CHECK_ZVAL_NULL_PATH ( arg ) ) {
return " a valid path " ;
}
2014-02-10 14:04:30 +08:00
break ;
}
}
case IS_ARRAY :
case IS_RESOURCE :
default :
2014-05-05 10:49:27 +08:00
return c = = ' S ' ? " string " : " a valid path " ;
2014-02-10 14:04:30 +08:00
}
}
break ;
2001-07-10 02:51:29 +08:00
case ' b ' :
{
zend_bool * p = va_arg ( * va , zend_bool * ) ;
zend_parse_parameters: allow ! for non pointers
This commit allows getting information about whether a certain value
was a NULL value by using the ! modifier together with the l/L, d and
b.
Example:
long l;
zend_bool is_null;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &l, &is_null)
For the specifiers l/L, d and b, NULL values are reported as 0, 0., or
false. But sometimes one wants to distinguish NULL from those other
values -- for instance, to give NULL the same effect as the argument
not having been passed.
The usual way this problem is handled is by fetching the parameter
with 'z' or 'Z', check if it is NULL and if not use
convert_to_long_ex()/convert_to_double_ex(), etc. Unfortunately, this
is not equivalent. convert_to_long_ex() does a cast, while zpp() is
stricter. For instance, zpp will not accept 'foo' for a long argument,
and it will emit a notice when encountering '5foo'.
In fact, the only way to otherwise zpp semantics (without duplicating
its logic) is to fetch the raw zval from the stack and check whether
it's NULL (with zpp itself or its relatives) and then run zpp again.
That is not an elegant solution.
2012-07-19 03:42:36 +08:00
if ( check_null ) {
zend_bool * p = va_arg ( * va , zend_bool * ) ;
2014-02-10 14:04:30 +08:00
* p = ( Z_TYPE_P ( arg ) = = IS_NULL ) ;
zend_parse_parameters: allow ! for non pointers
This commit allows getting information about whether a certain value
was a NULL value by using the ! modifier together with the l/L, d and
b.
Example:
long l;
zend_bool is_null;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &l, &is_null)
For the specifiers l/L, d and b, NULL values are reported as 0, 0., or
false. But sometimes one wants to distinguish NULL from those other
values -- for instance, to give NULL the same effect as the argument
not having been passed.
The usual way this problem is handled is by fetching the parameter
with 'z' or 'Z', check if it is NULL and if not use
convert_to_long_ex()/convert_to_double_ex(), etc. Unfortunately, this
is not equivalent. convert_to_long_ex() does a cast, while zpp() is
stricter. For instance, zpp will not accept 'foo' for a long argument,
and it will emit a notice when encountering '5foo'.
In fact, the only way to otherwise zpp semantics (without duplicating
its logic) is to fetch the raw zval from the stack and check whether
it's NULL (with zpp itself or its relatives) and then run zpp again.
That is not an elegant solution.
2012-07-19 03:42:36 +08:00
}
2014-02-10 14:04:30 +08:00
switch ( Z_TYPE_P ( arg ) ) {
2001-07-10 02:51:29 +08:00
case IS_NULL :
case IS_STRING :
2014-08-26 01:24:55 +08:00
case IS_LONG :
2001-07-10 02:51:29 +08:00
case IS_DOUBLE :
2014-04-30 22:32:42 +08:00
case IS_FALSE :
case IS_TRUE :
2001-07-10 02:51:29 +08:00
convert_to_boolean_ex ( arg ) ;
2014-04-30 22:32:42 +08:00
* p = Z_TYPE_P ( arg ) = = IS_TRUE ;
2001-07-10 02:51:29 +08:00
break ;
case IS_ARRAY :
case IS_OBJECT :
case IS_RESOURCE :
default :
return " boolean " ;
}
}
break ;
case ' r ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
2014-02-10 14:04:30 +08:00
if ( check_null & & Z_TYPE_P ( arg ) = = IS_NULL ) {
2007-11-03 03:40:39 +08:00
* p = NULL ;
break ;
}
2014-02-10 14:04:30 +08:00
if ( Z_TYPE_P ( arg ) = = IS_RESOURCE ) {
* p = arg ;
2007-11-03 03:40:39 +08:00
} else {
return " resource " ;
2006-05-10 07:53:23 +08:00
}
2001-07-10 02:51:29 +08:00
}
break ;
2008-11-25 02:10:36 +08:00
case ' A ' :
2001-07-10 02:51:29 +08:00
case ' a ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
2014-02-10 14:04:30 +08:00
if ( check_null & & Z_TYPE_P ( arg ) = = IS_NULL ) {
2007-11-03 03:40:39 +08:00
* p = NULL ;
break ;
}
2014-02-10 14:04:30 +08:00
if ( Z_TYPE_P ( arg ) = = IS_ARRAY | | ( c = = ' A ' & & Z_TYPE_P ( arg ) = = IS_OBJECT ) ) {
* p = arg ;
2007-11-03 03:40:39 +08:00
} else {
return " array " ;
2006-05-10 07:53:23 +08:00
}
2001-07-10 02:51:29 +08:00
}
break ;
2008-11-25 02:10:36 +08:00
case ' H ' :
2006-01-26 06:03:18 +08:00
case ' h ' :
{
HashTable * * p = va_arg ( * va , HashTable * * ) ;
2014-02-10 14:04:30 +08:00
if ( check_null & & Z_TYPE_P ( arg ) = = IS_NULL ) {
2007-11-03 03:40:39 +08:00
* p = NULL ;
break ;
}
2014-02-10 14:04:30 +08:00
if ( Z_TYPE_P ( arg ) = = IS_ARRAY ) {
* p = Z_ARRVAL_P ( arg ) ;
} else if ( c = = ' H ' & & Z_TYPE_P ( arg ) = = IS_OBJECT ) {
* p = HASH_OF ( arg ) ;
2008-11-25 02:10:36 +08:00
if ( * p = = NULL ) {
return " array " ;
}
2007-11-03 03:40:39 +08:00
} else {
return " array " ;
2006-01-26 06:03:18 +08:00
}
}
break ;
2001-07-10 02:51:29 +08:00
case ' o ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
2014-02-10 14:04:30 +08:00
if ( check_null & & Z_TYPE_P ( arg ) = = IS_NULL ) {
2007-11-03 03:40:39 +08:00
* p = NULL ;
break ;
}
2014-02-10 14:04:30 +08:00
if ( Z_TYPE_P ( arg ) = = IS_OBJECT ) {
* p = arg ;
2007-11-03 03:40:39 +08:00
} else {
return " object " ;
2006-05-10 07:53:23 +08:00
}
2001-07-10 02:51:29 +08:00
}
break ;
case ' O ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
zend_class_entry * ce = va_arg ( * va , zend_class_entry * ) ;
2003-08-02 01:51:56 +08:00
2014-02-10 14:04:30 +08:00
if ( check_null & & Z_TYPE_P ( arg ) = = IS_NULL ) {
2007-11-03 03:40:39 +08:00
* p = NULL ;
break ;
}
2014-02-10 14:04:30 +08:00
if ( Z_TYPE_P ( arg ) = = IS_OBJECT & &
( ! ce | | instanceof_function ( Z_OBJCE_P ( arg ) , ce TSRMLS_CC ) ) ) {
* p = arg ;
2003-08-02 01:51:56 +08:00
} else {
2007-11-03 03:40:39 +08:00
if ( ce ) {
2014-02-10 14:04:30 +08:00
return ce - > name - > val ;
2001-07-10 02:51:29 +08:00
} else {
2006-05-28 03:06:06 +08:00
return " object " ;
2001-07-10 02:51:29 +08:00
}
2003-08-02 01:51:56 +08:00
}
2001-07-10 02:51:29 +08:00
}
break ;
2006-02-28 06:23:21 +08:00
case ' C ' :
{
2014-02-10 14:04:30 +08:00
zend_class_entry * lookup , * * pce = va_arg ( * va , zend_class_entry * * ) ;
2006-02-28 06:23:21 +08:00
zend_class_entry * ce_base = * pce ;
2014-02-10 14:04:30 +08:00
if ( check_null & & Z_TYPE_P ( arg ) = = IS_NULL ) {
2006-05-24 06:22:11 +08:00
* pce = NULL ;
break ;
}
2006-02-28 06:23:21 +08:00
convert_to_string_ex ( arg ) ;
2014-02-10 14:04:30 +08:00
if ( ( lookup = zend_lookup_class ( Z_STR_P ( arg ) TSRMLS_CC ) ) = = NULL ) {
2006-02-28 06:23:21 +08:00
* pce = NULL ;
} else {
2014-02-10 14:04:30 +08:00
* pce = lookup ;
2006-02-28 06:23:21 +08:00
}
if ( ce_base ) {
2007-11-03 03:40:39 +08:00
if ( ( ! * pce | | ! instanceof_function ( * pce , ce_base TSRMLS_CC ) ) ) {
2008-02-02 05:27:55 +08:00
zend_spprintf ( error , 0 , " to be a class name derived from %s, '%s' given " ,
2014-02-22 00:53:09 +08:00
ce_base - > name - > val , Z_STRVAL_P ( arg ) ) ;
2006-02-28 06:23:21 +08:00
* pce = NULL ;
return " " ;
}
}
2006-05-24 06:22:11 +08:00
if ( ! * pce ) {
2008-02-02 05:27:55 +08:00
zend_spprintf ( error , 0 , " to be a valid class name, '%s' given " ,
2014-02-10 14:04:30 +08:00
Z_STRVAL_P ( arg ) ) ;
2006-02-28 06:23:21 +08:00
return " " ;
}
break ;
}
break ;
2006-06-07 17:43:54 +08:00
case ' f ' :
{
2007-11-03 03:40:39 +08:00
zend_fcall_info * fci = va_arg ( * va , zend_fcall_info * ) ;
2006-06-07 17:43:54 +08:00
zend_fcall_info_cache * fcc = va_arg ( * va , zend_fcall_info_cache * ) ;
2008-02-02 05:27:55 +08:00
char * is_callable_error = NULL ;
2006-06-07 17:43:54 +08:00
2014-02-10 14:04:30 +08:00
if ( check_null & & Z_TYPE_P ( arg ) = = IS_NULL ) {
2006-06-07 17:43:54 +08:00
fci - > size = 0 ;
fcc - > initialized = 0 ;
break ;
2007-11-03 03:40:39 +08:00
}
2014-02-10 14:04:30 +08:00
if ( zend_fcall_info_init ( arg , 0 , fci , fcc , NULL , & is_callable_error TSRMLS_CC ) = = SUCCESS ) {
2008-02-02 05:27:55 +08:00
if ( is_callable_error ) {
* severity = E_STRICT ;
zend_spprintf ( error , 0 , " to be a valid callback, %s " , is_callable_error ) ;
efree ( is_callable_error ) ;
2008-02-02 23:18:30 +08:00
* spec = spec_walk ;
2008-02-02 05:27:55 +08:00
return " " ;
}
2007-11-03 03:40:39 +08:00
break ;
2006-06-07 17:43:54 +08:00
} else {
2008-02-02 05:27:55 +08:00
if ( is_callable_error ) {
* severity = E_WARNING ;
zend_spprintf ( error , 0 , " to be a valid callback, %s " , is_callable_error ) ;
efree ( is_callable_error ) ;
return " " ;
} else {
return " valid callback " ;
}
2006-06-07 17:43:54 +08:00
}
}
2001-07-10 02:51:29 +08:00
case ' z ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
2014-02-10 14:04:30 +08:00
if ( check_null & & Z_TYPE_P ( arg ) = = IS_NULL ) {
2003-07-12 22:54:53 +08:00
* p = NULL ;
} else {
2014-02-19 18:35:28 +08:00
* p = real_arg ;
2003-07-12 22:54:53 +08:00
}
2003-07-11 18:21:39 +08:00
}
break ;
2007-11-03 03:40:39 +08:00
2014-02-10 14:04:30 +08:00
case ' Z ' :
2014-04-16 01:56:30 +08:00
/* 'Z' iz not supported anymore and should be replaced with 'z' */
2014-02-21 21:22:02 +08:00
ZEND_ASSERT ( c ! = ' Z ' ) ;
2001-07-10 02:51:29 +08:00
default :
return " unknown " ;
}
* spec = spec_walk ;
return NULL ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2014-02-10 14:04:30 +08:00
static int zend_parse_arg ( int arg_num , zval * arg , va_list * va , const char * * spec , int quiet TSRMLS_DC ) /* { { { */
2001-07-10 02:51:29 +08:00
{
2011-09-13 21:29:35 +08:00
const char * expected_type = NULL ;
char * error = NULL ;
2008-02-02 05:27:55 +08:00
int severity = E_WARNING ;
2001-07-10 02:51:29 +08:00
2008-02-02 05:27:55 +08:00
expected_type = zend_parse_arg_impl ( arg_num , arg , va , spec , & error , & severity TSRMLS_CC ) ;
2001-07-10 02:51:29 +08:00
if ( expected_type ) {
2008-02-02 05:27:55 +08:00
if ( ! quiet & & ( * expected_type | | error ) ) {
2011-09-13 21:29:35 +08:00
const char * space ;
const char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
2005-06-17 19:25:31 +08:00
2008-02-02 05:27:55 +08:00
if ( error ) {
zend_error ( severity , " %s%s%s() expects parameter %d %s " ,
class_name , space , get_active_function_name ( TSRMLS_C ) , arg_num , error ) ;
efree ( error ) ;
} else {
zend_error ( severity , " %s%s%s() expects parameter %d to be %s, %s given " ,
class_name , space , get_active_function_name ( TSRMLS_C ) , arg_num , expected_type ,
2014-02-10 14:04:30 +08:00
zend_zval_type_name ( arg ) ) ;
2008-02-02 05:27:55 +08:00
}
}
if ( severity ! = E_STRICT ) {
return FAILURE ;
2001-07-10 02:51:29 +08:00
}
}
2006-05-10 07:53:23 +08:00
2001-07-10 02:51:29 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2014-02-10 14:04:30 +08:00
ZEND_API int zend_parse_parameter ( int flags , int arg_num TSRMLS_DC , zval * arg , const char * spec , . . . )
Expose zend_parse_arg() as zend_parse_parameter()
Sometimes, one wants to accept several types for a given parameter. zpp
has special functionality for detecting the NULL type, since the NULL
type is frequently used to skip parameters.
However, supporting several types is otherwise very tedious. There are
many cases where this situation arises -- for instance one may want
to accept an arbitrary number of integer and expect them in an array,
but allow a bare integer too; one may want to accept something that
will be used as an array key (which can be either and int or a string);
one may want to accept integer and double numbers. A search for IS_LONG
reveals many situations where this need arises.
The usual solution is to fetch the argument with 'z'/'Z', check its
type, and then convert the argument, e.g. with convert_to_long_ex().
As explain in the last commit, this has different behavior and
generates inconsistency.
Another -- even more flawed strategy --, is to try zpp with a specific
format, forcing it quiet, and if it fails retrying with another form.
But because zpp changes the arguments directly in the stack (for
instance, using "l" converts the zval in the stack to IS_LONG), the
arguments may look different after the first zpp, leaving subtle bugs.
This commit also allows more complex scenarios, for instance where the
expected type of one parameter depends on other parameters.
2012-07-19 04:05:42 +08:00
{
va_list va ;
int ret ;
int quiet = flags & ZEND_PARSE_PARAMS_QUIET ;
va_start ( va , spec ) ;
ret = zend_parse_arg ( arg_num , arg , & va , & spec , quiet TSRMLS_CC ) ;
va_end ( va ) ;
return ret ;
}
2010-10-15 05:33:10 +08:00
static int zend_parse_va_args ( int num_args , const char * type_spec , va_list * va , int flags TSRMLS_DC ) /* { { { */
2001-07-10 02:51:29 +08:00
{
2010-10-15 05:33:10 +08:00
const char * spec_walk ;
2001-07-10 02:51:29 +08:00
int c , i ;
int min_num_args = - 1 ;
int max_num_args = 0 ;
2007-10-30 01:09:57 +08:00
int post_varargs = 0 ;
2014-02-10 14:04:30 +08:00
zval * arg ;
2001-07-10 02:51:29 +08:00
int arg_count ;
int quiet = flags & ZEND_PARSE_PARAMS_QUIET ;
2007-10-30 01:09:57 +08:00
zend_bool have_varargs = 0 ;
2014-02-18 05:41:23 +08:00
zval * * varargs = NULL ;
2007-11-03 03:40:39 +08:00
int * n_varargs = NULL ;
2001-07-10 02:51:29 +08:00
for ( spec_walk = type_spec ; * spec_walk ; spec_walk + + ) {
c = * spec_walk ;
switch ( c ) {
case ' l ' : case ' d ' :
case ' s ' : case ' b ' :
case ' r ' : case ' a ' :
case ' o ' : case ' O ' :
2003-07-12 22:54:53 +08:00
case ' z ' : case ' Z ' :
2006-02-28 06:23:21 +08:00
case ' C ' : case ' h ' :
2008-11-25 02:10:36 +08:00
case ' f ' : case ' A ' :
2011-06-07 05:28:16 +08:00
case ' H ' : case ' p ' :
2014-05-05 10:49:27 +08:00
case ' S ' : case ' P ' :
2014-08-26 01:24:55 +08:00
case ' L ' :
2001-07-10 02:51:29 +08:00
max_num_args + + ;
break ;
case ' | ' :
min_num_args = max_num_args ;
break ;
case ' / ' :
case ' ! ' :
/* Pass */
break ;
2007-10-30 01:09:57 +08:00
case ' * ' :
case ' + ' :
if ( have_varargs ) {
if ( ! quiet ) {
2014-07-03 02:01:25 +08:00
zend_function * active_function = EG ( current_execute_data ) - > func ;
2014-02-10 14:04:30 +08:00
const char * class_name = active_function - > common . scope ? active_function - > common . scope - > name - > val : " " ;
2007-10-30 01:09:57 +08:00
zend_error ( E_WARNING , " %s%s%s(): only one varargs specifier (* or +) is permitted " ,
class_name ,
class_name [ 0 ] ? " :: " : " " ,
2014-02-10 14:04:30 +08:00
active_function - > common . function_name - > val ) ;
2007-10-30 01:09:57 +08:00
}
return FAILURE ;
}
have_varargs = 1 ;
/* we expect at least one parameter in varargs */
if ( c = = ' + ' ) {
max_num_args + + ;
}
/* mark the beginning of varargs */
post_varargs = max_num_args ;
break ;
2001-07-10 02:51:29 +08:00
default :
if ( ! quiet ) {
2014-07-03 02:01:25 +08:00
zend_function * active_function = EG ( current_execute_data ) - > func ;
2014-02-10 14:04:30 +08:00
const char * class_name = active_function - > common . scope ? active_function - > common . scope - > name - > val : " " ;
2007-11-03 03:40:39 +08:00
zend_error ( E_WARNING , " %s%s%s(): bad type specifier while parsing parameters " ,
2003-08-13 15:02:44 +08:00
class_name ,
class_name [ 0 ] ? " :: " : " " ,
2014-02-10 14:04:30 +08:00
active_function - > common . function_name - > val ) ;
2001-07-10 02:51:29 +08:00
}
return FAILURE ;
}
}
if ( min_num_args < 0 ) {
min_num_args = max_num_args ;
}
2007-10-30 01:09:57 +08:00
if ( have_varargs ) {
/* calculate how many required args are at the end of the specifier list */
post_varargs = max_num_args - post_varargs ;
max_num_args = - 1 ;
}
if ( num_args < min_num_args | | ( num_args > max_num_args & & max_num_args > 0 ) ) {
2001-07-10 02:51:29 +08:00
if ( ! quiet ) {
2014-07-03 02:01:25 +08:00
zend_function * active_function = EG ( current_execute_data ) - > func ;
2014-02-10 14:04:30 +08:00
const char * class_name = active_function - > common . scope ? active_function - > common . scope - > name - > val : " " ;
2003-08-13 15:02:44 +08:00
zend_error ( E_WARNING , " %s%s%s() expects %s %d parameter%s, %d given " ,
class_name ,
class_name [ 0 ] ? " :: " : " " ,
2014-02-10 14:04:30 +08:00
active_function - > common . function_name - > val ,
2001-07-10 02:51:29 +08:00
min_num_args = = max_num_args ? " exactly " : num_args < min_num_args ? " at least " : " at most " ,
num_args < min_num_args ? min_num_args : max_num_args ,
( num_args < min_num_args ? min_num_args : max_num_args ) = = 1 ? " " : " s " ,
num_args ) ;
}
return FAILURE ;
}
2014-07-03 02:01:25 +08:00
arg_count = EG ( current_execute_data ) - > num_args ;
2001-07-10 02:51:29 +08:00
if ( num_args > arg_count ) {
2001-10-20 21:55:47 +08:00
zend_error ( E_WARNING , " %s(): could not obtain parameters for parsing " ,
2006-05-28 03:06:06 +08:00
get_active_function_name ( TSRMLS_C ) ) ;
2001-07-10 02:51:29 +08:00
return FAILURE ;
}
i = 0 ;
while ( num_args - - > 0 ) {
if ( * type_spec = = ' | ' ) {
type_spec + + ;
}
2007-10-30 01:09:57 +08:00
if ( * type_spec = = ' * ' | | * type_spec = = ' + ' ) {
int num_varargs = num_args + 1 - post_varargs ;
/* eat up the passed in storage even if it won't be filled in with varargs */
2014-02-18 05:41:23 +08:00
varargs = va_arg ( * va , zval * * ) ;
2007-11-03 03:40:39 +08:00
n_varargs = va_arg ( * va , int * ) ;
2007-10-30 01:09:57 +08:00
type_spec + + ;
if ( num_varargs > 0 ) {
* n_varargs = num_varargs ;
2014-07-03 02:01:25 +08:00
* varargs = ZEND_CALL_ARG ( EG ( current_execute_data ) , i + 1 ) ;
2007-10-30 01:09:57 +08:00
/* adjust how many args we have left and restart loop */
2014-03-05 15:10:52 +08:00
num_args + = 1 - num_varargs ;
i + = num_varargs ;
2007-10-30 01:09:57 +08:00
continue ;
} else {
* varargs = NULL ;
* n_varargs = 0 ;
}
}
2014-07-03 02:01:25 +08:00
arg = ZEND_CALL_ARG ( EG ( current_execute_data ) , i + 1 ) ;
2007-10-30 01:09:57 +08:00
2001-07-30 15:43:02 +08:00
if ( zend_parse_arg ( i + 1 , arg , va , & type_spec , quiet TSRMLS_CC ) = = FAILURE ) {
2007-11-03 03:40:39 +08:00
/* clean up varargs array if it was used */
if ( varargs & & * varargs ) {
* varargs = NULL ;
}
2001-07-10 02:51:29 +08:00
return FAILURE ;
}
i + + ;
}
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2007-11-03 03:40:39 +08:00
# define RETURN_IF_ZERO_ARGS(num_args, type_spec, quiet) { \
2007-10-30 18:17:41 +08:00
int __num_args = ( num_args ) ; \
2007-11-03 03:40:39 +08:00
\
2007-10-30 18:17:41 +08:00
if ( 0 = = ( type_spec ) [ 0 ] & & 0 ! = __num_args & & ! ( quiet ) ) { \
2011-09-13 21:29:35 +08:00
const char * __space ; \
const char * __class_name = get_active_class_name ( & __space TSRMLS_CC ) ; \
2007-10-30 18:17:41 +08:00
zend_error ( E_WARNING , " %s%s%s() expects exactly 0 parameters, %d given " , \
2007-11-03 03:40:39 +08:00
__class_name , __space , \
get_active_function_name ( TSRMLS_C ) , __num_args ) ; \
2007-10-30 18:17:41 +08:00
return FAILURE ; \
} \
}
2010-10-15 05:33:10 +08:00
ZEND_API int zend_parse_parameters_ex ( int flags , int num_args TSRMLS_DC , const char * type_spec , . . . ) /* { { { */
2001-07-10 02:51:29 +08:00
{
va_list va ;
int retval ;
2006-05-10 07:53:23 +08:00
2007-10-30 18:17:41 +08:00
RETURN_IF_ZERO_ARGS ( num_args , type_spec , flags & ZEND_PARSE_PARAMS_QUIET ) ;
2001-07-10 02:51:29 +08:00
va_start ( va , type_spec ) ;
2001-07-30 12:54:16 +08:00
retval = zend_parse_va_args ( num_args , type_spec , & va , flags TSRMLS_CC ) ;
2001-07-10 02:51:29 +08:00
va_end ( va ) ;
return retval ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2010-10-15 05:33:10 +08:00
ZEND_API int zend_parse_parameters ( int num_args TSRMLS_DC , const char * type_spec , . . . ) /* { { { */
2001-07-10 02:51:29 +08:00
{
va_list va ;
int retval ;
2006-05-10 07:53:23 +08:00
2007-10-30 18:17:41 +08:00
RETURN_IF_ZERO_ARGS ( num_args , type_spec , 0 ) ;
2001-07-10 02:51:29 +08:00
va_start ( va , type_spec ) ;
2001-07-30 12:54:16 +08:00
retval = zend_parse_va_args ( num_args , type_spec , & va , 0 TSRMLS_CC ) ;
2001-07-10 02:51:29 +08:00
va_end ( va ) ;
return retval ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2010-10-15 05:33:10 +08:00
ZEND_API int zend_parse_method_parameters ( int num_args TSRMLS_DC , zval * this_ptr , const char * type_spec , . . . ) /* { { { */
2003-02-03 07:30:14 +08:00
{
va_list va ;
int retval ;
2010-10-15 05:33:10 +08:00
const char * p = type_spec ;
2003-02-09 04:54:02 +08:00
zval * * object ;
zend_class_entry * ce ;
2003-02-03 07:30:14 +08:00
2014-05-07 03:56:01 +08:00
/* Just checking this_ptr is not enough, because fcall_common_helper does not set
* Z_OBJ ( EG ( This ) ) to NULL when calling an internal function with common . scope = = NULL .
* In that case EG ( This ) would still be the $ this from the calling code and we ' d take the
* wrong branch here . */
2014-07-03 02:01:25 +08:00
zend_bool is_method = EG ( current_execute_data ) - > func - > common . scope ! = NULL ;
2014-05-07 03:56:01 +08:00
if ( ! is_method | | ! this_ptr | | Z_TYPE_P ( this_ptr ) ! = IS_OBJECT ) {
2007-10-30 18:17:41 +08:00
RETURN_IF_ZERO_ARGS ( num_args , p , 0 ) ;
2003-02-09 04:54:02 +08:00
va_start ( va , type_spec ) ;
retval = zend_parse_va_args ( num_args , type_spec , & va , 0 TSRMLS_CC ) ;
va_end ( va ) ;
2003-08-01 00:30:15 +08:00
} else {
2003-02-09 04:54:02 +08:00
p + + ;
2007-10-30 18:17:41 +08:00
RETURN_IF_ZERO_ARGS ( num_args , p , 0 ) ;
2003-02-09 04:54:02 +08:00
va_start ( va , type_spec ) ;
2003-02-03 07:30:14 +08:00
2003-02-09 04:54:02 +08:00
object = va_arg ( va , zval * * ) ;
ce = va_arg ( va , zend_class_entry * ) ;
* object = this_ptr ;
2008-08-13 01:20:25 +08:00
2003-08-21 22:39:17 +08:00
if ( ce & & ! instanceof_function ( Z_OBJCE_P ( this_ptr ) , ce TSRMLS_CC ) ) {
zend_error ( E_CORE_ERROR , " %s::%s() must be derived from %s::%s " ,
2014-05-07 02:32:49 +08:00
Z_OBJCE_P ( this_ptr ) - > name - > val , get_active_function_name ( TSRMLS_C ) , ce - > name - > val , get_active_function_name ( TSRMLS_C ) ) ;
2003-08-21 22:39:17 +08:00
}
2003-02-03 07:30:14 +08:00
2003-02-09 04:54:02 +08:00
retval = zend_parse_va_args ( num_args , p , & va , 0 TSRMLS_CC ) ;
va_end ( va ) ;
}
2003-02-03 07:30:14 +08:00
return retval ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-02-03 07:30:14 +08:00
2010-10-15 05:33:10 +08:00
ZEND_API int zend_parse_method_parameters_ex ( int flags , int num_args TSRMLS_DC , zval * this_ptr , const char * type_spec , . . . ) /* { { { */
2003-02-03 07:30:14 +08:00
{
va_list va ;
int retval ;
2010-10-15 05:33:10 +08:00
const char * p = type_spec ;
2004-03-03 00:17:58 +08:00
zval * * object ;
zend_class_entry * ce ;
2003-02-03 07:30:14 +08:00
int quiet = flags & ZEND_PARSE_PARAMS_QUIET ;
2004-03-03 00:17:58 +08:00
if ( ! this_ptr ) {
2007-10-30 18:17:41 +08:00
RETURN_IF_ZERO_ARGS ( num_args , p , quiet ) ;
2004-03-03 00:17:58 +08:00
va_start ( va , type_spec ) ;
2009-12-24 08:15:13 +08:00
retval = zend_parse_va_args ( num_args , type_spec , & va , flags TSRMLS_CC ) ;
2004-03-03 00:17:58 +08:00
va_end ( va ) ;
} else {
p + + ;
2011-01-13 06:17:10 +08:00
RETURN_IF_ZERO_ARGS ( num_args , p , quiet ) ;
2007-10-30 18:17:41 +08:00
2004-03-03 00:17:58 +08:00
va_start ( va , type_spec ) ;
2003-02-03 07:30:14 +08:00
2004-03-03 00:17:58 +08:00
object = va_arg ( va , zval * * ) ;
ce = va_arg ( va , zend_class_entry * ) ;
* object = this_ptr ;
2008-08-13 01:20:25 +08:00
2004-03-03 00:17:58 +08:00
if ( ce & & ! instanceof_function ( Z_OBJCE_P ( this_ptr ) , ce TSRMLS_CC ) ) {
2003-02-03 07:30:14 +08:00
if ( ! quiet ) {
2004-03-03 00:17:58 +08:00
zend_error ( E_CORE_ERROR , " %s::%s() must be derived from %s::%s " ,
2014-02-10 14:04:30 +08:00
ce - > name - > val , get_active_function_name ( TSRMLS_C ) , Z_OBJCE_P ( this_ptr ) - > name - > val , get_active_function_name ( TSRMLS_C ) ) ;
2003-02-03 07:30:14 +08:00
}
2011-08-06 06:26:16 +08:00
va_end ( va ) ;
2003-02-03 07:30:14 +08:00
return FAILURE ;
}
2004-03-03 00:17:58 +08:00
retval = zend_parse_va_args ( num_args , p , & va , flags TSRMLS_CC ) ;
va_end ( va ) ;
}
2003-02-03 07:30:14 +08:00
return retval ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2004-03-03 00:17:58 +08:00
2001-07-10 02:51:29 +08:00
/* Argument parsing API -- andrei */
2008-05-27 18:29:33 +08:00
ZEND_API int _array_init ( zval * arg , uint size ZEND_FILE_LINE_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
ZVAL_NEW_ARR ( arg ) ;
2013-11-28 22:40:46 +08:00
_zend_hash_init ( Z_ARRVAL_P ( arg ) , size , ZVAL_PTR_DTOR , 0 ZEND_FILE_LINE_RELAY_CC ) ;
1999-04-08 02:10:10 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2006-05-10 07:53:23 +08:00
/* This function should be called after the constructor has been called
2003-08-30 07:27:22 +08:00
* because it may call __set from the uninitialized object otherwise . */
2014-06-04 06:11:26 +08:00
ZEND_API void zend_merge_properties ( zval * obj , HashTable * properties TSRMLS_DC ) /* { { { */
2003-08-30 07:27:22 +08:00
{
2011-09-13 21:29:35 +08:00
const zend_object_handlers * obj_ht = Z_OBJ_HT_P ( obj ) ;
2003-08-30 07:27:22 +08:00
zend_class_entry * old_scope = EG ( scope ) ;
2014-05-27 04:38:58 +08:00
zend_string * key ;
zval * value ;
2003-08-30 07:27:22 +08:00
EG ( scope ) = Z_OBJCE_P ( obj ) ;
2014-05-27 04:38:58 +08:00
ZEND_HASH_FOREACH_STR_KEY_VAL ( properties , key , value ) {
if ( key ) {
zval member ;
2014-08-26 01:24:55 +08:00
ZVAL_STR ( & member , zend_string_copy ( key ) ) ;
2014-07-08 00:54:31 +08:00
obj_ht - > write_property ( obj , & member , value , NULL TSRMLS_CC ) ;
2014-05-27 04:38:58 +08:00
zval_ptr_dtor ( & member ) ;
}
} ZEND_HASH_FOREACH_END ( ) ;
2003-08-30 07:27:22 +08:00
EG ( scope ) = old_scope ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-30 07:27:22 +08:00
2014-02-10 14:04:30 +08:00
static int zval_update_class_constant ( zval * pp , int is_static , int offset TSRMLS_DC ) /* { { { */
2013-03-19 20:59:01 +08:00
{
2014-03-27 17:39:09 +08:00
ZVAL_DEREF ( pp ) ;
2014-04-04 07:55:27 +08:00
if ( Z_CONSTANT_P ( pp ) ) {
2014-07-03 05:02:25 +08:00
zend_class_entry * * scope = EG ( current_execute_data ) ? & EG ( scope ) : & CG ( active_class_entry ) ;
2013-03-19 20:59:01 +08:00
if ( ( * scope ) - > parent ) {
zend_class_entry * ce = * scope ;
zend_property_info * prop_info ;
do {
2014-04-18 23:18:11 +08:00
ZEND_HASH_FOREACH_PTR ( & ce - > properties_info , prop_info ) {
2013-03-19 20:59:01 +08:00
if ( is_static = = ( ( prop_info - > flags & ZEND_ACC_STATIC ) ! = 0 ) & &
offset = = prop_info - > offset ) {
2013-03-19 21:42:18 +08:00
int ret ;
2013-03-19 20:59:01 +08:00
zend_class_entry * old_scope = * scope ;
* scope = prop_info - > ce ;
2014-04-12 01:18:58 +08:00
ret = zval_update_constant ( pp , 1 TSRMLS_CC ) ;
2013-03-19 20:59:01 +08:00
* scope = old_scope ;
return ret ;
}
2014-04-18 23:18:11 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2013-03-19 20:59:01 +08:00
ce = ce - > parent ;
} while ( ce ) ;
2013-11-01 23:16:58 +08:00
2013-03-19 20:59:01 +08:00
}
2014-04-12 01:18:58 +08:00
return zval_update_constant ( pp , 1 TSRMLS_CC ) ;
2013-03-19 20:59:01 +08:00
}
return 0 ;
}
/* }}} */
2007-11-03 03:40:39 +08:00
ZEND_API void zend_update_class_constants ( zend_class_entry * class_type TSRMLS_DC ) /* { { { */
2005-01-22 20:23:01 +08:00
{
2014-06-17 03:32:58 +08:00
int i ;
/* initialize static members of internal class */
if ( ! CE_STATIC_MEMBERS ( class_type ) & & class_type - > default_static_members_count ) {
zval * p ;
if ( class_type - > parent ) {
zend_update_class_constants ( class_type - > parent TSRMLS_CC ) ;
}
# if ZTS
CG ( static_members_table ) [ ( zend_intptr_t ) ( class_type - > static_members_table ) ] = emalloc ( sizeof ( zval * ) * class_type - > default_static_members_count ) ;
# else
class_type - > static_members_table = emalloc ( sizeof ( zval * ) * class_type - > default_static_members_count ) ;
# endif
for ( i = 0 ; i < class_type - > default_static_members_count ; i + + ) {
p = & class_type - > default_static_members_table [ i ] ;
if ( Z_ISREF_P ( p ) & &
class_type - > parent & &
i < class_type - > parent - > default_static_members_count & &
p = = & class_type - > parent - > default_static_members_table [ i ] & &
Z_TYPE ( CE_STATIC_MEMBERS ( class_type - > parent ) [ i ] ) ! = IS_UNDEF
) {
zval * q = & CE_STATIC_MEMBERS ( class_type - > parent ) [ i ] ;
ZVAL_NEW_REF ( q , q ) ;
ZVAL_COPY_VALUE ( & CE_STATIC_MEMBERS ( class_type ) [ i ] , q ) ;
Z_ADDREF_P ( q ) ;
} else {
ZVAL_DUP ( & CE_STATIC_MEMBERS ( class_type ) [ i ] , p ) ;
}
}
}
if ( ( class_type - > ce_flags & ZEND_ACC_CONSTANTS_UPDATED ) = = 0 ) {
2014-07-03 05:02:25 +08:00
zend_class_entry * * scope = EG ( current_execute_data ) ? & EG ( scope ) : & CG ( active_class_entry ) ;
2005-04-26 17:27:28 +08:00
zend_class_entry * old_scope = * scope ;
2014-06-17 01:11:52 +08:00
zval * val ;
2005-04-26 17:27:28 +08:00
* scope = class_type ;
2014-06-17 01:11:52 +08:00
ZEND_HASH_FOREACH_VAL ( & class_type - > constants_table , val ) {
zval_update_constant ( val , 1 TSRMLS_CC ) ;
} ZEND_HASH_FOREACH_END ( ) ;
2005-09-01 18:05:32 +08:00
2010-05-24 22:11:39 +08:00
for ( i = 0 ; i < class_type - > default_properties_count ; i + + ) {
2014-02-10 14:04:30 +08:00
if ( Z_TYPE ( class_type - > default_properties_table [ i ] ) ! = IS_UNDEF ) {
2013-03-19 20:59:01 +08:00
zval_update_class_constant ( & class_type - > default_properties_table [ i ] , 0 , i TSRMLS_CC ) ;
2010-05-24 22:11:39 +08:00
}
}
for ( i = 0 ; i < class_type - > default_static_members_count ; i + + ) {
2013-03-19 20:59:01 +08:00
zval_update_class_constant ( & CE_STATIC_MEMBERS ( class_type ) [ i ] , 1 , i TSRMLS_CC ) ;
2010-05-24 22:11:39 +08:00
}
2005-09-01 18:05:32 +08:00
2005-04-26 17:27:28 +08:00
* scope = old_scope ;
2010-09-15 15:38:52 +08:00
class_type - > ce_flags | = ZEND_ACC_CONSTANTS_UPDATED ;
2005-01-22 20:23:01 +08:00
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-01-22 20:23:01 +08:00
2010-05-24 22:11:39 +08:00
ZEND_API void object_properties_init ( zend_object * object , zend_class_entry * class_type ) /* { { { */
{
int i ;
if ( class_type - > default_properties_count ) {
for ( i = 0 ; i < class_type - > default_properties_count ; i + + ) {
2012-04-06 00:46:52 +08:00
# if ZTS
2014-04-09 21:51:28 +08:00
ZVAL_DUP ( & object - > properties_table [ i ] , & class_type - > default_properties_table [ i ] ) ;
2012-04-06 00:46:52 +08:00
# else
2014-04-09 21:51:28 +08:00
ZVAL_COPY ( & object - > properties_table [ i ] , & class_type - > default_properties_table [ i ] ) ;
2012-04-06 00:46:52 +08:00
# endif
2010-05-24 22:11:39 +08:00
}
object - > properties = NULL ;
}
}
/* }}} */
2014-04-09 21:51:28 +08:00
ZEND_API void object_properties_init_ex ( zend_object * object , HashTable * properties TSRMLS_DC ) /* { { { */
2014-03-26 22:07:31 +08:00
{
object - > properties = properties ;
if ( object - > ce - > default_properties_count ) {
zval * prop , tmp ;
zend_string * key ;
zend_property_info * property_info ;
2014-04-22 21:46:34 +08:00
ZEND_HASH_FOREACH_STR_KEY_VAL ( properties , key , prop ) {
2014-03-26 22:07:31 +08:00
ZVAL_STR ( & tmp , key ) ;
property_info = zend_get_property_info ( object - > ce , & tmp , 1 TSRMLS_CC ) ;
if ( property_info & &
( property_info - > flags & ZEND_ACC_STATIC ) = = 0 & &
property_info - > offset > = 0 ) {
ZVAL_COPY_VALUE ( & object - > properties_table [ property_info - > offset ] , prop ) ;
ZVAL_INDIRECT ( prop , & object - > properties_table [ property_info - > offset ] ) ;
}
2014-04-18 23:18:11 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2014-03-26 22:07:31 +08:00
}
}
/* }}} */
2014-04-09 21:51:28 +08:00
ZEND_API void object_properties_load ( zend_object * object , HashTable * properties TSRMLS_DC ) /* { { { */
2014-03-26 22:07:31 +08:00
{
zval * prop , tmp ;
zend_string * key ;
zend_property_info * property_info ;
2014-04-22 21:46:34 +08:00
ZEND_HASH_FOREACH_STR_KEY_VAL ( properties , key , prop ) {
2014-03-26 22:07:31 +08:00
ZVAL_STR ( & tmp , key ) ;
property_info = zend_get_property_info ( object - > ce , & tmp , 1 TSRMLS_CC ) ;
if ( property_info & &
( property_info - > flags & ZEND_ACC_STATIC ) = = 0 & &
property_info - > offset > = 0 ) {
zval_ptr_dtor ( & object - > properties_table [ property_info - > offset ] ) ;
ZVAL_COPY_VALUE ( & object - > properties_table [ property_info - > offset ] , prop ) ;
zval_add_ref ( & object - > properties_table [ property_info - > offset ] ) ;
if ( object - > properties ) {
ZVAL_INDIRECT ( & tmp , & object - > properties_table [ property_info - > offset ] ) ;
2014-09-14 04:21:35 +08:00
zend_hash_update ( object - > properties , key , & tmp ) ;
2014-03-26 22:07:31 +08:00
}
} else {
if ( ! object - > properties ) {
rebuild_object_properties ( object ) ;
}
prop = zend_hash_update ( object - > properties , key , prop ) ;
zval_add_ref ( prop ) ;
}
2014-04-18 23:18:11 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2014-03-26 22:07:31 +08:00
}
/* }}} */
2003-08-30 07:27:22 +08:00
/* This function requires 'properties' to contain all props declared in the
2006-05-10 07:53:23 +08:00
* class and all props being public . If only a subset is given or the class
2013-06-11 05:20:18 +08:00
* has protected members then you need to merge the properties separately by
2003-08-30 07:27:22 +08:00
* calling zend_merge_properties ( ) . */
2007-11-03 03:40:39 +08:00
ZEND_API int _object_and_properties_init ( zval * arg , zend_class_entry * class_type , HashTable * properties ZEND_FILE_LINE_DC TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2004-06-05 22:59:21 +08:00
if ( class_type - > ce_flags & ( ZEND_ACC_INTERFACE | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS ) ) {
2011-11-01 06:59:00 +08:00
char * what = ( class_type - > ce_flags & ZEND_ACC_INTERFACE ) ? " interface "
: ( ( class_type - > ce_flags & ZEND_ACC_TRAIT ) = = ZEND_ACC_TRAIT ) ? " trait "
: " abstract class " ;
2014-02-10 14:04:30 +08:00
zend_error ( E_ERROR , " Cannot instantiate %s %s " , what , class_type - > name - > val ) ;
2004-06-05 22:59:21 +08:00
}
2005-01-22 20:23:01 +08:00
zend_update_class_constants ( class_type TSRMLS_CC ) ;
2006-05-10 07:53:23 +08:00
2002-09-15 15:45:26 +08:00
if ( class_type - > create_object = = NULL ) {
2014-02-10 14:04:30 +08:00
ZVAL_OBJ ( arg , zend_objects_new ( class_type TSRMLS_CC ) ) ;
2002-02-07 22:08:43 +08:00
if ( properties ) {
2014-04-09 21:51:28 +08:00
object_properties_init_ex ( Z_OBJ_P ( arg ) , properties TSRMLS_CC ) ;
2002-02-07 22:08:43 +08:00
} else {
2014-02-10 14:04:30 +08:00
object_properties_init ( Z_OBJ_P ( arg ) , class_type ) ;
2002-02-07 22:08:43 +08:00
}
2001-08-12 02:26:47 +08:00
} else {
2014-02-10 14:04:30 +08:00
ZVAL_OBJ ( arg , class_type - > create_object ( class_type TSRMLS_CC ) ) ;
2002-02-07 22:08:43 +08:00
}
1999-04-08 02:10:10 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int _object_init_ex ( zval * arg , zend_class_entry * class_type ZEND_FILE_LINE_DC TSRMLS_DC ) /* { { { */
2001-08-12 02:26:47 +08:00
{
2002-04-30 17:56:48 +08:00
return _object_and_properties_init ( arg , class_type , 0 ZEND_FILE_LINE_RELAY_CC TSRMLS_CC ) ;
2001-08-12 02:26:47 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int _object_init ( zval * arg ZEND_FILE_LINE_DC TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2002-04-30 17:56:48 +08:00
return _object_init_ex ( arg , zend_standard_class_def ZEND_FILE_LINE_RELAY_CC TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_function ( zval * arg , const char * key , void ( * function_ptr ) ( INTERNAL_FUNCTION_PARAMETERS ) ) /* { { { */
1999-10-04 19:42:46 +08:00
{
zend_error ( E_WARNING , " add_assoc_function() is no longer supported " ) ;
return FAILURE ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int add_assoc_long_ex ( zval * arg , const char * key , uint key_len , zend_long n ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval * ret , tmp ;
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & tmp , n ) ;
2014-02-10 14:04:30 +08:00
ret = zend_symtable_str_update ( Z_ARRVAL_P ( arg ) , key , key_len , & tmp ) ;
return ret ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_null_ex ( zval * arg , const char * key , uint key_len ) /* { { { */
1999-12-31 21:56:59 +08:00
{
2014-02-10 14:04:30 +08:00
zval * ret , tmp ;
ZVAL_NULL ( & tmp ) ;
ret = zend_symtable_str_update ( Z_ARRVAL_P ( arg ) , key , key_len , & tmp ) ;
return ret ? SUCCESS : FAILURE ;
1999-12-31 21:56:59 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-12-31 21:56:59 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_bool_ex ( zval * arg , const char * key , uint key_len , int b ) /* { { { */
1999-10-04 19:42:46 +08:00
{
2014-02-10 14:04:30 +08:00
zval * ret , tmp ;
ZVAL_BOOL ( & tmp , b ) ;
ret = zend_symtable_str_update ( Z_ARRVAL_P ( arg ) , key , key_len , & tmp ) ;
return ret ? SUCCESS : FAILURE ;
1999-10-04 19:42:46 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2014-02-10 14:04:30 +08:00
ZEND_API int add_assoc_resource_ex ( zval * arg , const char * key , uint key_len , zend_resource * r ) /* { { { */
1999-10-04 19:42:46 +08:00
{
2014-02-10 14:04:30 +08:00
zval * ret , tmp ;
ZVAL_RES ( & tmp , r ) ;
ret = zend_symtable_str_update ( Z_ARRVAL_P ( arg ) , key , key_len , & tmp ) ;
return ret ? SUCCESS : FAILURE ;
1999-10-04 19:42:46 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_double_ex ( zval * arg , const char * key , uint key_len , double d ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval * ret , tmp ;
ZVAL_DOUBLE ( & tmp , d ) ;
ret = zend_symtable_str_update ( Z_ARRVAL_P ( arg ) , key , key_len , & tmp ) ;
return ret ? SUCCESS : FAILURE ;
}
/* }}} */
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZEND_API int add_assoc_str_ex ( zval * arg , const char * key , uint key_len , zend_string * str ) /* { { { */
{
zval * ret , tmp ;
1999-04-08 02:10:10 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STR ( & tmp , str ) ;
ret = zend_symtable_str_update ( Z_ARRVAL_P ( arg ) , key , key_len , & tmp ) ;
return ret ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-04-15 19:40:40 +08:00
ZEND_API int add_assoc_string_ex ( zval * arg , const char * key , uint key_len , char * str ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval * ret , tmp ;
ZVAL_STRING ( & tmp , str ) ;
ret = zend_symtable_str_update ( Z_ARRVAL_P ( arg ) , key , key_len , & tmp ) ;
return ret ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-29 01:17:47 +08:00
ZEND_API int add_assoc_stringl_ex ( zval * arg , const char * key , uint key_len , char * str , size_t length ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval * ret , tmp ;
ZVAL_STRINGL ( & tmp , str , length ) ;
ret = zend_symtable_str_update ( Z_ARRVAL_P ( arg ) , key , key_len , & tmp ) ;
return ret ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_zval_ex ( zval * arg , const char * key , uint key_len , zval * value ) /* { { { */
2001-01-19 16:40:49 +08:00
{
2014-02-10 14:04:30 +08:00
zval * ret ;
ret = zend_symtable_str_update ( Z_ARRVAL_P ( arg ) , key , key_len , value ) ;
return ret ? SUCCESS : FAILURE ;
2001-01-19 16:40:49 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-01-19 16:40:49 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int add_index_long ( zval * arg , zend_ulong index , zend_long n ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
1999-10-04 19:42:46 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & tmp , n ) ;
2014-02-10 14:04:30 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int add_index_null ( zval * arg , zend_ulong index ) /* { { { */
1999-12-31 21:56:59 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
1999-12-31 21:56:59 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( & tmp ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ? SUCCESS : FAILURE ;
2001-01-21 03:16:38 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-12-31 21:56:59 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int add_index_bool ( zval * arg , zend_ulong index , int b ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( & tmp , b ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ? SUCCESS : FAILURE ;
1999-10-04 19:42:46 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int add_index_resource ( zval * arg , zend_ulong index , zend_resource * r ) /* { { { */
1999-10-04 19:42:46 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_RES ( & tmp , r ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int add_index_double ( zval * arg , zend_ulong index , double d ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_DOUBLE ( & tmp , d ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ? SUCCESS : FAILURE ;
2014-02-14 18:55:48 +08:00
}
/* }}} */
2014-08-26 01:24:55 +08:00
ZEND_API int add_index_str ( zval * arg , zend_ulong index , zend_string * str ) /* { { { */
2014-02-14 18:55:48 +08:00
{
zval tmp ;
ZVAL_STR ( & tmp , str ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int add_index_string ( zval * arg , zend_ulong index , const char * str ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & tmp , str ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-29 01:17:47 +08:00
ZEND_API int add_index_stringl ( zval * arg , zend_ulong index , const char * str , size_t length ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( & tmp , str , length ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ? SUCCESS : FAILURE ;
2001-01-21 03:16:38 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int add_index_zval ( zval * arg , zend_ulong index , zval * value ) /* { { { */
2001-01-21 03:16:38 +08:00
{
2014-02-10 14:04:30 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , value ) ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int add_next_index_long ( zval * arg , zend_long n ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & tmp , n ) ;
2014-02-10 14:04:30 +08:00
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp ) ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_null ( zval * arg ) /* { { { */
1999-12-31 21:56:59 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( & tmp ) ;
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp ) ? SUCCESS : FAILURE ;
1999-12-31 21:56:59 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-12-31 21:56:59 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_bool ( zval * arg , int b ) /* { { { */
1999-10-04 19:42:46 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( & tmp , b ) ;
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp ) ? SUCCESS : FAILURE ;
1999-10-04 19:42:46 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2014-02-10 14:04:30 +08:00
ZEND_API int add_next_index_resource ( zval * arg , zend_resource * r ) /* { { { */
1999-10-04 19:42:46 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_RES ( & tmp , r ) ;
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp ) ? SUCCESS : FAILURE ;
1999-10-04 19:42:46 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_double ( zval * arg , double d ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_DOUBLE ( & tmp , d ) ;
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp ) ? SUCCESS : FAILURE ;
}
/* }}} */
ZEND_API int add_next_index_str ( zval * arg , zend_string * str ) /* { { { */
{
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-25 15:47:24 +08:00
ZVAL_STR ( & tmp , str ) ;
2014-02-10 14:04:30 +08:00
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp ) ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-04-15 19:40:40 +08:00
ZEND_API int add_next_index_string ( zval * arg , const char * str ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2001-01-21 03:16:38 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & tmp , str ) ;
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp ) ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-29 01:17:47 +08:00
ZEND_API int add_next_index_stringl ( zval * arg , const char * str , size_t length ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2001-01-21 03:16:38 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( & tmp , str , length ) ;
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp ) ? SUCCESS : FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_zval ( zval * arg , zval * value ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , value ) ? SUCCESS : FAILURE ;
2001-01-21 03:16:38 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-04-15 19:40:40 +08:00
ZEND_API zval * add_get_assoc_string_ex ( zval * arg , const char * key , uint key_len , const char * str ) /* { { { */
2001-01-21 03:16:38 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp , * ret ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & tmp , str ) ;
ret = zend_symtable_str_update ( Z_ARRVAL_P ( arg ) , key , key_len , & tmp ) ;
return ret ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-29 01:17:47 +08:00
ZEND_API zval * add_get_assoc_stringl_ex ( zval * arg , const char * key , uint key_len , const char * str , size_t length ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp , * ret ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( & tmp , str , length ) ;
ret = zend_symtable_str_update ( Z_ARRVAL_P ( arg ) , key , key_len , & tmp ) ;
return ret ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API zval * add_get_index_long ( zval * arg , zend_ulong index , zend_long l ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & tmp , l ) ;
2014-02-10 14:04:30 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API zval * add_get_index_double ( zval * arg , zend_ulong index , double d ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_DOUBLE ( & tmp , d ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API zval * add_get_index_str ( zval * arg , zend_ulong index , zend_string * str ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2007-11-03 03:40:39 +08:00
2014-02-25 15:47:24 +08:00
ZVAL_STR ( & tmp , str ) ;
2014-02-10 14:04:30 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API zval * add_get_index_string ( zval * arg , zend_ulong index , const char * str ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2007-11-03 03:40:39 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & tmp , str ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ;
}
/* }}} */
2014-08-29 01:17:47 +08:00
ZEND_API zval * add_get_index_stringl ( zval * arg , zend_ulong index , const char * str , size_t length ) /* { { { */
2014-02-10 14:04:30 +08:00
{
zval tmp ;
2007-11-03 03:40:39 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( & tmp , str , length ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , & tmp ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-04-09 21:51:28 +08:00
ZEND_API int array_set_zval_key ( HashTable * ht , zval * key , zval * value TSRMLS_DC ) /* { { { */
2013-02-17 02:13:36 +08:00
{
2014-02-10 14:04:30 +08:00
zval * result ;
2013-02-17 02:13:36 +08:00
switch ( Z_TYPE_P ( key ) ) {
case IS_STRING :
2014-02-10 14:04:30 +08:00
result = zend_symtable_update ( ht , Z_STR_P ( key ) , value ) ;
2013-02-17 02:13:36 +08:00
break ;
case IS_NULL :
2014-02-10 14:04:30 +08:00
result = zend_symtable_update ( ht , STR_EMPTY_ALLOC ( ) , value ) ;
2013-02-17 02:13:36 +08:00
break ;
case IS_RESOURCE :
2014-08-26 02:22:49 +08:00
zend_error ( E_STRICT , " Resource ID# " ZEND_LONG_FMT " used as offset, casting to integer (%pd) " , Z_RES_HANDLE_P ( key ) , Z_RES_HANDLE_P ( key ) ) ;
2014-02-24 17:12:53 +08:00
result = zend_hash_index_update ( ht , Z_RES_HANDLE_P ( key ) , value ) ;
break ;
2014-04-30 22:32:42 +08:00
case IS_FALSE :
result = zend_hash_index_update ( ht , 0 , value ) ;
break ;
case IS_TRUE :
result = zend_hash_index_update ( ht , 1 , value ) ;
break ;
2014-08-26 01:24:55 +08:00
case IS_LONG :
result = zend_hash_index_update ( ht , Z_LVAL_P ( key ) , value ) ;
2013-02-17 02:13:36 +08:00
break ;
case IS_DOUBLE :
2014-08-26 01:24:55 +08:00
result = zend_hash_index_update ( ht , zend_dval_to_lval ( Z_DVAL_P ( key ) ) , value ) ;
2013-02-17 02:13:36 +08:00
break ;
default :
zend_error ( E_WARNING , " Illegal offset type " ) ;
2014-02-10 14:04:30 +08:00
result = NULL ;
2013-02-17 02:13:36 +08:00
}
2014-02-10 14:04:30 +08:00
if ( result ) {
2014-02-28 22:44:50 +08:00
if ( Z_REFCOUNTED_P ( result ) ) {
Z_ADDREF_P ( result ) ;
}
2014-02-10 14:04:30 +08:00
return SUCCESS ;
} else {
return FAILURE ;
2013-02-17 02:13:36 +08:00
}
}
/* }}} */
2014-08-26 01:24:55 +08:00
ZEND_API int add_property_long_ex ( zval * arg , const char * key , uint key_len , zend_long n TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
zval z_key ;
2007-11-03 03:40:39 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & tmp , n ) ;
2014-03-01 03:05:22 +08:00
ZVAL_STRINGL ( & z_key , key , key_len ) ;
2014-07-08 00:54:31 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , & z_key , & tmp , NULL TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int add_property_bool_ex ( zval * arg , const char * key , uint key_len , zend_long b TSRMLS_DC ) /* { { { */
2000-02-02 07:12:48 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
zval z_key ;
2003-01-14 20:15:09 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( & tmp , b ) ;
2014-03-01 03:05:22 +08:00
ZVAL_STRINGL ( & z_key , key , key_len ) ;
2014-07-08 00:54:31 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , & z_key , & tmp , NULL TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
2000-02-02 07:12:48 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2000-02-02 07:12:48 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int add_property_null_ex ( zval * arg , const char * key , uint key_len TSRMLS_DC ) /* { { { */
2000-02-02 07:12:48 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
zval z_key ;
2007-11-03 03:40:39 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( & tmp ) ;
2014-03-01 03:05:22 +08:00
ZVAL_STRINGL ( & z_key , key , key_len ) ;
2014-07-08 00:54:31 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , & z_key , & tmp , NULL TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
2000-02-02 07:12:48 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2000-02-02 07:12:48 +08:00
2014-02-10 14:04:30 +08:00
ZEND_API int add_property_resource_ex ( zval * arg , const char * key , uint key_len , zend_resource * r TSRMLS_DC ) /* { { { */
1999-09-29 23:25:06 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
zval z_key ;
2005-11-23 19:15:11 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_RES ( & tmp , r ) ;
2014-03-01 03:05:22 +08:00
ZVAL_STRINGL ( & z_key , key , key_len ) ;
2014-07-08 00:54:31 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , & z_key , & tmp , NULL TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
1999-09-29 23:25:06 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-09-29 23:25:06 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int add_property_double_ex ( zval * arg , const char * key , uint key_len , double d TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
zval z_key ;
2003-01-01 20:38:55 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_DOUBLE ( & tmp , d ) ;
2014-03-01 03:05:22 +08:00
ZVAL_STRINGL ( & z_key , key , key_len ) ;
2014-07-08 00:54:31 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , & z_key , & tmp , NULL TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-05-15 06:44:47 +08:00
ZEND_API int add_property_str_ex ( zval * arg , const char * key , uint key_len , zend_string * str TSRMLS_DC ) /* { { { */
{
zval tmp ;
zval z_key ;
ZVAL_STR ( & tmp , str ) ;
ZVAL_STRINGL ( & z_key , key , key_len ) ;
2014-07-08 00:54:31 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , & z_key , & tmp , NULL TSRMLS_CC ) ;
2014-05-15 20:18:19 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2014-05-15 06:44:47 +08:00
zval_ptr_dtor ( & z_key ) ;
return SUCCESS ;
}
/* }}} */
2014-04-15 19:40:40 +08:00
ZEND_API int add_property_string_ex ( zval * arg , const char * key , uint key_len , const char * str TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
zval z_key ;
1999-04-08 02:10:10 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & tmp , str ) ;
2014-03-01 03:05:22 +08:00
ZVAL_STRINGL ( & z_key , key , key_len ) ;
2014-07-08 00:54:31 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , & z_key , & tmp , NULL TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
2001-01-21 03:16:38 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-29 01:17:47 +08:00
ZEND_API int add_property_stringl_ex ( zval * arg , const char * key , uint key_len , const char * str , size_t length TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
zval z_key ;
2001-01-21 03:16:38 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( & tmp , str , length ) ;
2014-03-01 03:05:22 +08:00
ZVAL_STRINGL ( & z_key , key , key_len ) ;
2014-07-08 00:54:31 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , & z_key , & tmp , NULL TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int add_property_zval_ex ( zval * arg , const char * key , uint key_len , zval * value TSRMLS_DC ) /* { { { */
2001-01-21 03:16:38 +08:00
{
2014-02-10 14:04:30 +08:00
zval z_key ;
2003-01-14 20:15:09 +08:00
2014-03-01 03:05:22 +08:00
ZVAL_STRINGL ( & z_key , key , key_len ) ;
2014-07-08 00:54:31 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , & z_key , value , NULL TSRMLS_CC ) ;
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
2001-01-21 03:16:38 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int zend_startup_module_ex ( zend_module_entry * module TSRMLS_DC ) /* { { { */
2005-06-17 17:36:26 +08:00
{
int name_len ;
2014-02-10 14:04:30 +08:00
zend_string * lcname ;
2005-06-17 17:36:26 +08:00
if ( module - > module_started ) {
return SUCCESS ;
}
module - > module_started = 1 ;
/* Check module dependencies */
if ( module - > deps ) {
2007-09-28 02:00:48 +08:00
const zend_module_dep * dep = module - > deps ;
2005-06-17 17:36:26 +08:00
while ( dep - > name ) {
if ( dep - > type = = MODULE_DEP_REQUIRED ) {
zend_module_entry * req_mod ;
name_len = strlen ( dep - > name ) ;
2014-08-26 01:24:55 +08:00
lcname = zend_string_alloc ( name_len , 0 ) ;
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( lcname - > val , dep - > name , name_len ) ;
2005-06-17 17:36:26 +08:00
2014-02-10 14:04:30 +08:00
if ( ( req_mod = zend_hash_find_ptr ( & module_registry , lcname ) ) = = NULL | | ! req_mod - > module_started ) {
2014-08-26 01:24:55 +08:00
zend_string_free ( lcname ) ;
2005-06-17 17:36:26 +08:00
/* TODO: Check version relationship */
2005-08-08 22:25:05 +08:00
zend_error ( E_CORE_WARNING , " Cannot load module '%s' because required module '%s' is not loaded " , module - > name , dep - > name ) ;
2005-06-17 17:36:26 +08:00
module - > module_started = 0 ;
return FAILURE ;
2006-05-10 07:53:23 +08:00
}
2014-08-26 01:24:55 +08:00
zend_string_free ( lcname ) ;
2005-06-17 17:36:26 +08:00
}
+ + dep ;
}
}
2006-06-15 22:03:21 +08:00
/* Initialize module globals */
if ( module - > globals_size ) {
# ifdef ZTS
ts_allocate_id ( module - > globals_id_ptr , module - > globals_size , ( ts_allocate_ctor ) module - > globals_ctor , ( ts_allocate_dtor ) module - > globals_dtor ) ;
# else
if ( module - > globals_ctor ) {
module - > globals_ctor ( module - > globals_ptr TSRMLS_CC ) ;
}
# endif
}
2005-06-17 17:36:26 +08:00
if ( module - > module_startup_func ) {
EG ( current_module ) = module ;
if ( module - > module_startup_func ( module - > type , module - > module_number TSRMLS_CC ) = = FAILURE ) {
zend_error ( E_CORE_ERROR , " Unable to start %s module " , module - > name ) ;
EG ( current_module ) = NULL ;
return FAILURE ;
}
EG ( current_module ) = NULL ;
}
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-06-17 17:36:26 +08:00
2014-02-17 15:50:32 +08:00
static int zend_startup_module_zval ( zval * zv TSRMLS_DC ) /* { { { */
{
zend_module_entry * module = Z_PTR_P ( zv ) ;
return zend_startup_module_ex ( module TSRMLS_CC ) ;
}
/* }}} */
2007-11-03 03:40:39 +08:00
static void zend_sort_modules ( void * base , size_t count , size_t siz , compare_func_t compare TSRMLS_DC ) /* { { { */
2005-06-17 17:36:26 +08:00
{
2014-02-10 14:04:30 +08:00
Bucket * b1 = base ;
Bucket * b2 ;
Bucket * end = b1 + count ;
Bucket tmp ;
2005-06-17 17:36:26 +08:00
zend_module_entry * m , * r ;
while ( b1 < end ) {
try_again :
2014-02-10 14:04:30 +08:00
m = ( zend_module_entry * ) Z_PTR ( b1 - > val ) ;
2005-06-17 17:36:26 +08:00
if ( ! m - > module_started & & m - > deps ) {
2007-09-28 02:00:48 +08:00
const zend_module_dep * dep = m - > deps ;
2005-06-17 17:36:26 +08:00
while ( dep - > name ) {
if ( dep - > type = = MODULE_DEP_REQUIRED | | dep - > type = = MODULE_DEP_OPTIONAL ) {
b2 = b1 + 1 ;
while ( b2 < end ) {
2014-02-10 14:04:30 +08:00
r = ( zend_module_entry * ) Z_PTR ( b2 - > val ) ;
2007-07-06 20:17:58 +08:00
if ( strcasecmp ( dep - > name , r - > name ) = = 0 ) {
2007-11-03 03:40:39 +08:00
tmp = * b1 ;
2007-07-06 20:17:58 +08:00
* b1 = * b2 ;
* b2 = tmp ;
goto try_again ;
}
b2 + + ;
}
}
dep + + ;
2006-05-10 07:53:23 +08:00
}
2005-06-17 17:36:26 +08:00
}
b1 + + ;
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-06-17 17:36:26 +08:00
2010-10-15 15:30:24 +08:00
ZEND_API void zend_collect_module_handlers ( TSRMLS_D ) /* { { { */
2010-07-06 19:40:17 +08:00
{
zend_module_entry * module ;
int startup_count = 0 ;
int shutdown_count = 0 ;
int post_deactivate_count = 0 ;
2014-02-17 15:50:32 +08:00
zend_class_entry * ce ;
2010-07-06 19:40:17 +08:00
int class_count = 0 ;
/* Collect extensions with request startup/shutdown handlers */
2014-04-18 23:18:11 +08:00
ZEND_HASH_FOREACH_PTR ( & module_registry , module ) {
2010-07-06 19:40:17 +08:00
if ( module - > request_startup_func ) {
startup_count + + ;
}
if ( module - > request_shutdown_func ) {
shutdown_count + + ;
}
if ( module - > post_deactivate_func ) {
post_deactivate_count + + ;
}
2014-04-18 23:18:11 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2010-07-06 19:40:17 +08:00
module_request_startup_handlers = ( zend_module_entry * * ) malloc (
sizeof ( zend_module_entry * ) *
( startup_count + 1 +
shutdown_count + 1 +
post_deactivate_count + 1 ) ) ;
module_request_startup_handlers [ startup_count ] = NULL ;
module_request_shutdown_handlers = module_request_startup_handlers + startup_count + 1 ;
module_request_shutdown_handlers [ shutdown_count ] = NULL ;
module_post_deactivate_handlers = module_request_shutdown_handlers + shutdown_count + 1 ;
module_post_deactivate_handlers [ post_deactivate_count ] = NULL ;
startup_count = 0 ;
2014-04-18 23:18:11 +08:00
ZEND_HASH_FOREACH_PTR ( & module_registry , module ) {
2010-07-06 19:40:17 +08:00
if ( module - > request_startup_func ) {
module_request_startup_handlers [ startup_count + + ] = module ;
}
if ( module - > request_shutdown_func ) {
module_request_shutdown_handlers [ - - shutdown_count ] = module ;
}
if ( module - > post_deactivate_func ) {
module_post_deactivate_handlers [ - - post_deactivate_count ] = module ;
}
2014-04-18 23:18:11 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2010-07-06 19:40:17 +08:00
/* Collect internal classes with static members */
2014-04-18 23:18:11 +08:00
ZEND_HASH_FOREACH_PTR ( CG ( class_table ) , ce ) {
2014-02-17 15:50:32 +08:00
if ( ce - > type = = ZEND_INTERNAL_CLASS & &
ce - > default_static_members_count > 0 ) {
2010-07-06 19:40:17 +08:00
class_count + + ;
}
2014-04-18 23:18:11 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2010-07-06 19:40:17 +08:00
class_cleanup_handlers = ( zend_class_entry * * ) malloc (
sizeof ( zend_class_entry * ) *
( class_count + 1 ) ) ;
class_cleanup_handlers [ class_count ] = NULL ;
if ( class_count ) {
2014-04-18 23:18:11 +08:00
ZEND_HASH_FOREACH_PTR ( CG ( class_table ) , ce ) {
2014-02-17 15:50:32 +08:00
if ( ce - > type = = ZEND_INTERNAL_CLASS & &
ce - > default_static_members_count > 0 ) {
class_cleanup_handlers [ - - class_count ] = ce ;
2010-07-06 19:40:17 +08:00
}
2014-04-18 23:18:11 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2010-07-06 19:40:17 +08:00
}
}
/* }}} */
2007-11-03 03:40:39 +08:00
ZEND_API int zend_startup_modules ( TSRMLS_D ) /* { { { */
2005-06-17 17:36:26 +08:00
{
zend_hash_sort ( & module_registry , zend_sort_modules , NULL , 0 TSRMLS_CC ) ;
2014-02-17 15:50:32 +08:00
zend_hash_apply ( & module_registry , zend_startup_module_zval TSRMLS_CC ) ;
2005-06-17 17:36:26 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-06-17 17:36:26 +08:00
2010-07-06 19:40:17 +08:00
ZEND_API void zend_destroy_modules ( void ) /* { { { */
{
free ( class_cleanup_handlers ) ;
free ( module_request_startup_handlers ) ;
zend_hash_graceful_reverse_destroy ( & module_registry ) ;
}
/* }}} */
2007-11-03 03:40:39 +08:00
ZEND_API zend_module_entry * zend_register_module_ex ( zend_module_entry * module TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2004-05-13 07:05:28 +08:00
int name_len ;
2014-02-10 14:04:30 +08:00
zend_string * lcname ;
2014-02-12 22:08:11 +08:00
zend_module_entry * module_ptr ;
2006-05-10 07:53:23 +08:00
2004-05-13 07:05:28 +08:00
if ( ! module ) {
2005-07-19 00:20:08 +08:00
return NULL ;
2004-05-13 07:05:28 +08:00
}
2004-05-13 07:03:38 +08:00
2004-05-13 07:05:28 +08:00
#if 0
2007-11-03 03:40:39 +08:00
zend_printf ( " %s: Registering module %d \n " , module - > name , module - > module_number ) ;
2004-05-13 07:05:28 +08:00
# endif
2005-06-17 17:36:26 +08:00
/* Check module dependencies */
if ( module - > deps ) {
2007-09-28 02:00:48 +08:00
const zend_module_dep * dep = module - > deps ;
2005-06-17 17:36:26 +08:00
while ( dep - > name ) {
if ( dep - > type = = MODULE_DEP_CONFLICTS ) {
name_len = strlen ( dep - > name ) ;
2014-08-26 01:24:55 +08:00
lcname = zend_string_alloc ( name_len , 0 ) ;
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( lcname - > val , dep - > name , name_len ) ;
2005-06-17 17:36:26 +08:00
2014-02-10 14:04:30 +08:00
if ( zend_hash_exists ( & module_registry , lcname ) ) {
2014-08-26 01:24:55 +08:00
zend_string_free ( lcname ) ;
2005-06-17 17:36:26 +08:00
/* TODO: Check version relationship */
zend_error ( E_CORE_WARNING , " Cannot load module '%s' because conflicting module '%s' is already loaded " , module - > name , dep - > name ) ;
2005-07-19 00:20:08 +08:00
return NULL ;
2006-05-10 07:53:23 +08:00
}
2014-08-26 01:24:55 +08:00
zend_string_free ( lcname ) ;
2005-06-17 17:36:26 +08:00
}
+ + dep ;
}
}
2004-05-13 07:05:28 +08:00
name_len = strlen ( module - > name ) ;
2014-08-26 01:24:55 +08:00
lcname = zend_string_alloc ( name_len , 1 ) ;
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( lcname - > val , module - > name , name_len ) ;
2004-05-13 07:05:28 +08:00
2014-02-12 22:08:11 +08:00
if ( ( module_ptr = zend_hash_add_mem ( & module_registry , lcname , module , sizeof ( zend_module_entry ) ) ) = = NULL ) {
2004-05-13 07:05:28 +08:00
zend_error ( E_CORE_WARNING , " Module '%s' already loaded " , module - > name ) ;
2014-08-26 01:24:55 +08:00
zend_string_release ( lcname ) ;
2005-07-19 00:20:08 +08:00
return NULL ;
2004-05-13 07:05:28 +08:00
}
2014-08-26 01:24:55 +08:00
zend_string_release ( lcname ) ;
2014-02-12 22:08:11 +08:00
module = module_ptr ;
2006-05-10 07:53:23 +08:00
EG ( current_module ) = module ;
2004-05-13 07:05:28 +08:00
if ( module - > functions & & zend_register_functions ( NULL , module - > functions , NULL , module - > type TSRMLS_CC ) = = FAILURE ) {
2006-05-10 07:53:23 +08:00
EG ( current_module ) = NULL ;
2007-11-03 03:40:39 +08:00
zend_error ( E_CORE_WARNING , " %s: Unable to register functions, unable to load " , module - > name ) ;
2005-07-19 00:20:08 +08:00
return NULL ;
2004-05-13 07:05:28 +08:00
}
2006-05-10 07:53:23 +08:00
EG ( current_module ) = NULL ;
2005-07-19 00:20:08 +08:00
return module ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API zend_module_entry * zend_register_internal_module ( zend_module_entry * module TSRMLS_DC ) /* { { { */
2004-05-13 07:05:28 +08:00
{
module - > module_number = zend_next_free_module ( ) ;
module - > type = MODULE_PERSISTENT ;
return zend_register_module_ex ( module TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2004-05-13 07:05:28 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API void zend_check_magic_method_implementation ( const zend_class_entry * ce , const zend_function * fptr , int error_type TSRMLS_DC ) /* { { { */
2004-09-10 00:51:45 +08:00
{
char lcname [ 16 ] ;
int name_len ;
2007-11-03 03:40:39 +08:00
/* we don't care if the function name is longer, in fact lowercasing only
2004-09-10 00:51:45 +08:00
* the beginning of the name speeds up the check process */
2014-02-10 14:04:30 +08:00
name_len = fptr - > common . function_name - > len ;
zend_str_tolower_copy ( lcname , fptr - > common . function_name - > val , MIN ( name_len , sizeof ( lcname ) - 1 ) ) ;
2004-09-10 00:51:45 +08:00
lcname [ sizeof ( lcname ) - 1 ] = ' \0 ' ; /* zend_str_tolower_copy won't necessarily set the zero byte */
2013-12-17 15:09:52 +08:00
if ( name_len = = sizeof ( ZEND_DESTRUCTOR_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_DESTRUCTOR_FUNC_NAME , sizeof ( ZEND_DESTRUCTOR_FUNC_NAME ) - 1 ) & & fptr - > common . num_args ! = 0 ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Destructor %s::%s() cannot take arguments " , ce - > name - > val , ZEND_DESTRUCTOR_FUNC_NAME ) ;
2013-12-17 15:09:52 +08:00
} else if ( name_len = = sizeof ( ZEND_CLONE_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_CLONE_FUNC_NAME , sizeof ( ZEND_CLONE_FUNC_NAME ) - 1 ) & & fptr - > common . num_args ! = 0 ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot accept any arguments " , ce - > name - > val , ZEND_CLONE_FUNC_NAME ) ;
2013-12-17 15:09:52 +08:00
} else if ( name_len = = sizeof ( ZEND_GET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_GET_FUNC_NAME , sizeof ( ZEND_GET_FUNC_NAME ) - 1 ) ) {
2007-08-31 20:36:14 +08:00
if ( fptr - > common . num_args ! = 1 ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() must take exactly 1 argument " , ce - > name - > val , ZEND_GET_FUNC_NAME ) ;
2007-08-31 20:36:14 +08:00
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name - > val , ZEND_GET_FUNC_NAME ) ;
2007-08-31 20:36:14 +08:00
}
2013-12-17 15:09:52 +08:00
} else if ( name_len = = sizeof ( ZEND_SET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_SET_FUNC_NAME , sizeof ( ZEND_SET_FUNC_NAME ) - 1 ) ) {
2007-08-31 20:36:14 +08:00
if ( fptr - > common . num_args ! = 2 ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() must take exactly 2 arguments " , ce - > name - > val , ZEND_SET_FUNC_NAME ) ;
2007-08-31 20:36:14 +08:00
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) | | ARG_SHOULD_BE_SENT_BY_REF ( fptr , 2 ) ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name - > val , ZEND_SET_FUNC_NAME ) ;
2007-08-31 20:36:14 +08:00
}
2013-12-17 15:09:52 +08:00
} else if ( name_len = = sizeof ( ZEND_UNSET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_UNSET_FUNC_NAME , sizeof ( ZEND_UNSET_FUNC_NAME ) - 1 ) ) {
2007-08-31 20:36:14 +08:00
if ( fptr - > common . num_args ! = 1 ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() must take exactly 1 argument " , ce - > name - > val , ZEND_UNSET_FUNC_NAME ) ;
2007-08-31 20:36:14 +08:00
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name - > val , ZEND_UNSET_FUNC_NAME ) ;
2007-08-31 20:36:14 +08:00
}
2013-12-17 15:09:52 +08:00
} else if ( name_len = = sizeof ( ZEND_ISSET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_ISSET_FUNC_NAME , sizeof ( ZEND_ISSET_FUNC_NAME ) - 1 ) ) {
2007-08-31 20:36:14 +08:00
if ( fptr - > common . num_args ! = 1 ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() must take exactly 1 argument " , ce - > name - > val , ZEND_ISSET_FUNC_NAME ) ;
2007-08-31 20:36:14 +08:00
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name - > val , ZEND_ISSET_FUNC_NAME ) ;
2007-08-31 20:36:14 +08:00
}
2013-12-17 15:09:52 +08:00
} else if ( name_len = = sizeof ( ZEND_CALL_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_CALL_FUNC_NAME , sizeof ( ZEND_CALL_FUNC_NAME ) - 1 ) ) {
2007-08-31 20:36:14 +08:00
if ( fptr - > common . num_args ! = 2 ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() must take exactly 2 arguments " , ce - > name - > val , ZEND_CALL_FUNC_NAME ) ;
2007-08-31 20:36:14 +08:00
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) | | ARG_SHOULD_BE_SENT_BY_REF ( fptr , 2 ) ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name - > val , ZEND_CALL_FUNC_NAME ) ;
2007-08-31 20:36:14 +08:00
}
2007-09-29 16:52:40 +08:00
} else if ( name_len = = sizeof ( ZEND_CALLSTATIC_FUNC_NAME ) - 1 & &
2007-11-03 03:40:39 +08:00
! memcmp ( lcname , ZEND_CALLSTATIC_FUNC_NAME , sizeof ( ZEND_CALLSTATIC_FUNC_NAME ) - 1 )
) {
2007-09-29 16:52:40 +08:00
if ( fptr - > common . num_args ! = 2 ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() must take exactly 2 arguments " , ce - > name - > val , ZEND_CALLSTATIC_FUNC_NAME ) ;
2007-09-29 16:52:40 +08:00
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) | | ARG_SHOULD_BE_SENT_BY_REF ( fptr , 2 ) ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name - > val , ZEND_CALLSTATIC_FUNC_NAME ) ;
2007-09-29 16:52:40 +08:00
}
} else if ( name_len = = sizeof ( ZEND_TOSTRING_FUNC_NAME ) - 1 & &
2007-11-03 03:40:39 +08:00
! memcmp ( lcname , ZEND_TOSTRING_FUNC_NAME , sizeof ( ZEND_TOSTRING_FUNC_NAME ) - 1 ) & & fptr - > common . num_args ! = 0
) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot take arguments " , ce - > name - > val , ZEND_TOSTRING_FUNC_NAME ) ;
2014-02-18 11:13:00 +08:00
} else if ( name_len = = sizeof ( ZEND_DEBUGINFO_FUNC_NAME ) - 1 & &
! memcmp ( lcname , ZEND_DEBUGINFO_FUNC_NAME , sizeof ( ZEND_DEBUGINFO_FUNC_NAME ) - 1 ) & & fptr - > common . num_args ! = 0 ) {
2014-04-26 04:32:51 +08:00
zend_error ( error_type , " Method %s::%s() cannot take arguments " , ce - > name - > val , ZEND_DEBUGINFO_FUNC_NAME ) ;
2004-09-10 00:51:45 +08:00
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
/* registers all functions in *library_functions in the function hash */
2007-11-03 03:40:39 +08:00
ZEND_API int zend_register_functions ( zend_class_entry * scope , const zend_function_entry * functions , HashTable * function_table , int type TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2007-09-28 02:00:48 +08:00
const zend_function_entry * ptr = functions ;
2003-01-10 22:41:53 +08:00
zend_function function , * reg_function ;
1999-12-28 03:17:40 +08:00
zend_internal_function * internal_function = ( zend_internal_function * ) & function ;
2013-09-14 00:45:02 +08:00
int count = 0 , unload = 0 ;
1999-05-28 20:06:59 +08:00
HashTable * target_function_table = function_table ;
2000-06-13 04:22:17 +08:00
int error_type ;
2014-02-18 11:13:00 +08:00
zend_function * ctor = NULL , * dtor = NULL , * clone = NULL , * __get = NULL , * __set = NULL , * __unset = NULL , * __isset = NULL , * __call = NULL , * __callstatic = NULL , * __tostring = NULL , * __debugInfo = NULL ;
2014-02-10 14:04:30 +08:00
zend_string * lowercase_name ;
2003-06-02 20:13:11 +08:00
int fname_len ;
2010-10-15 05:33:10 +08:00
const char * lc_class_name = NULL ;
2006-02-07 04:37:11 +08:00
int class_name_len = 0 ;
1999-04-08 02:10:10 +08:00
2000-06-13 04:22:17 +08:00
if ( type = = MODULE_PERSISTENT ) {
error_type = E_CORE_WARNING ;
} else {
error_type = E_WARNING ;
}
1999-05-28 20:06:59 +08:00
if ( ! target_function_table ) {
target_function_table = CG ( function_table ) ;
}
1999-12-28 01:29:35 +08:00
internal_function - > type = ZEND_INTERNAL_FUNCTION ;
2007-05-30 18:17:43 +08:00
internal_function - > module = EG ( current_module ) ;
2007-11-03 03:40:39 +08:00
2004-09-10 00:51:45 +08:00
if ( scope ) {
2014-02-10 14:04:30 +08:00
class_name_len = scope - > name - > len ;
2014-02-17 15:50:32 +08:00
if ( ( lc_class_name = zend_memrchr ( scope - > name - > val , ' \\ ' , class_name_len ) ) ) {
2008-11-04 23:58:55 +08:00
+ + lc_class_name ;
2014-02-10 14:04:30 +08:00
class_name_len - = ( lc_class_name - scope - > name - > val ) ;
2008-05-05 17:44:39 +08:00
lc_class_name = zend_str_tolower_dup ( lc_class_name , class_name_len ) ;
} else {
2014-02-10 14:04:30 +08:00
lc_class_name = zend_str_tolower_dup ( scope - > name - > val , class_name_len ) ;
2008-05-05 17:44:39 +08:00
}
2004-09-10 00:51:45 +08:00
}
2003-04-04 20:25:47 +08:00
1999-04-08 02:10:10 +08:00
while ( ptr - > fname ) {
2014-02-10 14:04:30 +08:00
fname_len = strlen ( ptr - > fname ) ;
1999-12-28 01:29:35 +08:00
internal_function - > handler = ptr - > handler ;
2014-08-26 01:24:55 +08:00
internal_function - > function_name = zend_new_interned_string ( zend_string_init ( ptr - > fname , fname_len , 1 ) TSRMLS_CC ) ;
2002-11-24 04:44:12 +08:00
internal_function - > scope = scope ;
2003-03-29 19:19:38 +08:00
internal_function - > prototype = NULL ;
2003-08-04 05:04:39 +08:00
if ( ptr - > flags ) {
2003-08-04 05:06:23 +08:00
if ( ! ( ptr - > flags & ZEND_ACC_PPP_MASK ) ) {
2006-02-26 02:25:45 +08:00
if ( ptr - > flags ! = ZEND_ACC_DEPRECATED | | scope ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Invalid access level for %s%s%s() - access must be exactly one of public, protected or private " , scope ? scope - > name - > val : " " , scope ? " :: " : " " , ptr - > fname ) ;
2006-02-26 02:25:45 +08:00
}
2006-02-19 18:39:31 +08:00
internal_function - > fn_flags = ZEND_ACC_PUBLIC | ptr - > flags ;
2003-08-24 19:07:30 +08:00
} else {
internal_function - > fn_flags = ptr - > flags ;
2003-08-04 05:06:23 +08:00
}
2003-08-04 05:04:39 +08:00
} else {
internal_function - > fn_flags = ZEND_ACC_PUBLIC ;
}
2010-09-15 15:38:52 +08:00
if ( ptr - > arg_info ) {
zend_internal_function_info * info = ( zend_internal_function_info * ) ptr - > arg_info ;
internal_function - > arg_info = ( zend_arg_info * ) ptr - > arg_info + 1 ;
internal_function - > num_args = ptr - > num_args ;
/* Currently you cannot denote that the function can accept less arguments than num_args */
if ( info - > required_num_args = = - 1 ) {
internal_function - > required_num_args = ptr - > num_args ;
} else {
internal_function - > required_num_args = info - > required_num_args ;
}
if ( info - > return_reference ) {
internal_function - > fn_flags | = ZEND_ACC_RETURN_REFERENCE ;
}
2013-09-27 00:39:17 +08:00
if ( ptr - > arg_info [ ptr - > num_args ] . is_variadic ) {
internal_function - > fn_flags | = ZEND_ACC_VARIADIC ;
}
2010-09-15 15:38:52 +08:00
} else {
internal_function - > arg_info = NULL ;
internal_function - > num_args = 0 ;
internal_function - > required_num_args = 0 ;
}
2004-02-27 17:14:55 +08:00
if ( ptr - > flags & ZEND_ACC_ABSTRACT ) {
2003-08-17 08:57:35 +08:00
if ( scope ) {
2004-02-28 02:20:53 +08:00
/* This is a class that must be abstract itself. Here we set the check info. */
2004-03-10 00:38:37 +08:00
scope - > ce_flags | = ZEND_ACC_IMPLICIT_ABSTRACT_CLASS ;
2004-02-27 17:14:55 +08:00
if ( ! ( scope - > ce_flags & ZEND_ACC_INTERFACE ) ) {
2004-02-28 02:20:53 +08:00
/* Since the class is not an interface it needs to be declared as a abstract class. */
2004-03-10 00:38:37 +08:00
/* Since here we are handling internal functions only we can add the keyword flag. */
2008-02-19 14:52:43 +08:00
/* This time we set the flag for the keyword 'abstract'. */
2004-03-10 00:38:37 +08:00
scope - > ce_flags | = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS ;
2004-02-27 17:14:55 +08:00
}
2003-08-17 08:57:35 +08:00
}
2006-06-04 18:27:28 +08:00
if ( ptr - > flags & ZEND_ACC_STATIC & & ( ! scope | | ! ( scope - > ce_flags & ZEND_ACC_INTERFACE ) ) ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Static function %s%s%s() cannot be abstract " , scope ? scope - > name - > val : " " , scope ? " :: " : " " , ptr - > fname ) ;
2006-06-04 18:27:28 +08:00
}
2003-08-17 08:57:35 +08:00
} else {
2004-02-27 17:14:55 +08:00
if ( scope & & ( scope - > ce_flags & ZEND_ACC_INTERFACE ) ) {
2011-09-13 21:29:35 +08:00
efree ( ( char * ) lc_class_name ) ;
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Interface %s cannot contain non abstract method %s() " , scope - > name - > val , ptr - > fname ) ;
2003-09-18 18:21:38 +08:00
return FAILURE ;
}
2003-08-17 08:57:35 +08:00
if ( ! internal_function - > handler ) {
2005-10-27 22:07:30 +08:00
if ( scope ) {
2011-09-13 21:29:35 +08:00
efree ( ( char * ) lc_class_name ) ;
2005-10-27 22:07:30 +08:00
}
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s%s%s() cannot be a NULL function " , scope ? scope - > name - > val : " " , scope ? " :: " : " " , ptr - > fname ) ;
2003-08-17 08:57:35 +08:00
zend_unregister_functions ( functions , count , target_function_table TSRMLS_CC ) ;
return FAILURE ;
}
1999-04-08 02:10:10 +08:00
}
2014-08-26 01:24:55 +08:00
lowercase_name = zend_string_alloc ( fname_len , 1 ) ;
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( lowercase_name - > val , ptr - > fname , fname_len ) ;
lowercase_name = zend_new_interned_string ( lowercase_name TSRMLS_CC ) ;
2014-02-17 21:59:18 +08:00
reg_function = malloc ( sizeof ( zend_internal_function ) ) ;
memcpy ( reg_function , & function , sizeof ( zend_internal_function ) ) ;
if ( zend_hash_add_ptr ( target_function_table , lowercase_name , reg_function ) = = NULL ) {
2011-07-10 20:37:42 +08:00
unload = 1 ;
2014-02-17 21:59:18 +08:00
free ( reg_function ) ;
2014-08-26 01:24:55 +08:00
zend_string_release ( lowercase_name ) ;
2011-07-10 20:37:42 +08:00
break ;
1999-04-08 02:10:10 +08:00
}
2013-11-28 15:44:14 +08:00
/* If types of arguments have to be checked */
if ( reg_function - > common . arg_info & & reg_function - > common . num_args ) {
int i ;
for ( i = 0 ; i < reg_function - > common . num_args ; i + + ) {
if ( reg_function - > common . arg_info [ i ] . class_name | |
reg_function - > common . arg_info [ i ] . type_hint ) {
reg_function - > common . fn_flags | = ZEND_ACC_HAS_TYPE_HINTS ;
break ;
}
}
}
2003-01-10 22:41:53 +08:00
if ( scope ) {
2003-06-02 20:13:11 +08:00
/* Look for ctor, dtor, clone
* If it ' s an old - style constructor , store it only if we don ' t have
* a constructor already .
*/
2014-02-18 20:27:38 +08:00
if ( ( fname_len = = class_name_len ) & & ! ctor & & ! memcmp ( lowercase_name - > val , lc_class_name , class_name_len + 1 ) ) {
2003-06-02 20:13:11 +08:00
ctor = reg_function ;
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lowercase_name , ZEND_CONSTRUCTOR_FUNC_NAME ) ) {
2003-06-02 20:13:11 +08:00
ctor = reg_function ;
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lowercase_name , ZEND_DESTRUCTOR_FUNC_NAME ) ) {
2003-06-02 20:13:11 +08:00
dtor = reg_function ;
2004-03-27 04:05:35 +08:00
if ( internal_function - > num_args ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Destructor %s::%s() cannot take arguments " , scope - > name - > val , ptr - > fname ) ;
2004-03-27 04:05:35 +08:00
}
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lowercase_name , ZEND_CLONE_FUNC_NAME ) ) {
2003-06-02 20:13:11 +08:00
clone = reg_function ;
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lowercase_name , ZEND_CALL_FUNC_NAME ) ) {
2004-09-10 00:51:45 +08:00
__call = reg_function ;
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lowercase_name , ZEND_CALLSTATIC_FUNC_NAME ) ) {
2007-09-29 16:52:40 +08:00
__callstatic = reg_function ;
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lowercase_name , ZEND_TOSTRING_FUNC_NAME ) ) {
2006-05-10 07:53:23 +08:00
__tostring = reg_function ;
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lowercase_name , ZEND_GET_FUNC_NAME ) ) {
2004-09-10 00:51:45 +08:00
__get = reg_function ;
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lowercase_name , ZEND_SET_FUNC_NAME ) ) {
2004-09-10 00:51:45 +08:00
__set = reg_function ;
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lowercase_name , ZEND_UNSET_FUNC_NAME ) ) {
2005-07-08 00:07:09 +08:00
__unset = reg_function ;
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lowercase_name , ZEND_ISSET_FUNC_NAME ) ) {
2005-07-08 00:07:09 +08:00
__isset = reg_function ;
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lowercase_name , ZEND_DEBUGINFO_FUNC_NAME ) ) {
2014-02-18 11:13:00 +08:00
__debugInfo = reg_function ;
2004-09-10 00:51:45 +08:00
} else {
reg_function = NULL ;
}
if ( reg_function ) {
zend_check_magic_method_implementation ( scope , reg_function , error_type TSRMLS_CC ) ;
2003-01-10 22:41:53 +08:00
}
}
1999-04-08 02:10:10 +08:00
ptr + + ;
count + + ;
2014-08-26 01:24:55 +08:00
zend_string_release ( lowercase_name ) ;
1999-04-08 02:10:10 +08:00
}
if ( unload ) { /* before unloading, display all remaining bad function in the module */
2004-09-10 00:51:45 +08:00
if ( scope ) {
2011-09-13 21:29:35 +08:00
efree ( ( char * ) lc_class_name ) ;
2004-09-10 00:51:45 +08:00
}
1999-04-08 02:10:10 +08:00
while ( ptr - > fname ) {
2008-08-22 22:51:30 +08:00
fname_len = strlen ( ptr - > fname ) ;
2014-08-26 01:24:55 +08:00
lowercase_name = zend_string_alloc ( fname_len , 0 ) ;
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( lowercase_name - > val , ptr - > fname , fname_len ) ;
if ( zend_hash_exists ( target_function_table , lowercase_name ) ) {
zend_error ( error_type , " Function registration failed - duplicate name - %s%s%s " , scope ? scope - > name - > val : " " , scope ? " :: " : " " , ptr - > fname ) ;
1999-04-08 02:10:10 +08:00
}
2014-08-26 01:24:55 +08:00
zend_string_free ( lowercase_name ) ;
1999-04-08 02:10:10 +08:00
ptr + + ;
}
2001-07-30 09:48:22 +08:00
zend_unregister_functions ( functions , count , target_function_table TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
return FAILURE ;
}
2003-01-10 22:41:53 +08:00
if ( scope ) {
scope - > constructor = ctor ;
scope - > destructor = dtor ;
scope - > clone = clone ;
2004-09-10 00:51:45 +08:00
scope - > __call = __call ;
2007-09-29 16:52:40 +08:00
scope - > __callstatic = __callstatic ;
2006-05-10 07:53:23 +08:00
scope - > __tostring = __tostring ;
2004-09-10 00:51:45 +08:00
scope - > __get = __get ;
scope - > __set = __set ;
2005-07-08 00:07:09 +08:00
scope - > __unset = __unset ;
scope - > __isset = __isset ;
2014-02-18 11:13:00 +08:00
scope - > __debugInfo = __debugInfo ;
2003-08-23 23:38:58 +08:00
if ( ctor ) {
2004-01-25 00:59:24 +08:00
ctor - > common . fn_flags | = ZEND_ACC_CTOR ;
2003-09-02 21:26:25 +08:00
if ( ctor - > common . fn_flags & ZEND_ACC_STATIC ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Constructor %s::%s() cannot be static " , scope - > name - > val , ctor - > common . function_name - > val ) ;
2003-09-02 21:26:25 +08:00
}
2004-01-25 00:59:24 +08:00
ctor - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
2003-08-23 23:38:58 +08:00
}
if ( dtor ) {
2004-01-25 00:59:24 +08:00
dtor - > common . fn_flags | = ZEND_ACC_DTOR ;
2003-09-02 21:26:25 +08:00
if ( dtor - > common . fn_flags & ZEND_ACC_STATIC ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Destructor %s::%s() cannot be static " , scope - > name - > val , dtor - > common . function_name - > val ) ;
2003-09-02 21:26:25 +08:00
}
2004-01-25 00:59:24 +08:00
dtor - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
2003-08-23 23:38:58 +08:00
}
2004-01-24 04:52:39 +08:00
if ( clone ) {
2004-01-25 00:59:24 +08:00
clone - > common . fn_flags | = ZEND_ACC_CLONE ;
2004-01-24 04:52:39 +08:00
if ( clone - > common . fn_flags & ZEND_ACC_STATIC ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Constructor %s::%s() cannot be static " , scope - > name - > val , clone - > common . function_name - > val ) ;
2004-01-24 04:52:39 +08:00
}
2004-01-25 00:59:24 +08:00
clone - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
2004-01-24 04:52:39 +08:00
}
2004-09-10 00:51:45 +08:00
if ( __call ) {
if ( __call - > common . fn_flags & ZEND_ACC_STATIC ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name - > val , __call - > common . function_name - > val ) ;
2004-09-10 00:51:45 +08:00
}
__call - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
2007-09-29 16:52:40 +08:00
if ( __callstatic ) {
if ( ! ( __callstatic - > common . fn_flags & ZEND_ACC_STATIC ) ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() must be static " , scope - > name - > val , __callstatic - > common . function_name - > val ) ;
2007-09-29 16:52:40 +08:00
}
__callstatic - > common . fn_flags | = ZEND_ACC_STATIC ;
}
2006-05-10 07:53:23 +08:00
if ( __tostring ) {
if ( __tostring - > common . fn_flags & ZEND_ACC_STATIC ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name - > val , __tostring - > common . function_name - > val ) ;
2006-05-10 07:53:23 +08:00
}
__tostring - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
2004-09-10 00:51:45 +08:00
if ( __get ) {
if ( __get - > common . fn_flags & ZEND_ACC_STATIC ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name - > val , __get - > common . function_name - > val ) ;
2004-09-10 00:51:45 +08:00
}
__get - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
if ( __set ) {
if ( __set - > common . fn_flags & ZEND_ACC_STATIC ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name - > val , __set - > common . function_name - > val ) ;
2004-09-10 00:51:45 +08:00
}
__set - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
2005-07-08 00:07:09 +08:00
if ( __unset ) {
if ( __unset - > common . fn_flags & ZEND_ACC_STATIC ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name - > val , __unset - > common . function_name - > val ) ;
2005-07-08 00:07:09 +08:00
}
__unset - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
if ( __isset ) {
if ( __isset - > common . fn_flags & ZEND_ACC_STATIC ) {
2014-02-10 14:04:30 +08:00
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name - > val , __isset - > common . function_name - > val ) ;
2005-07-08 00:07:09 +08:00
}
__isset - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
2014-02-18 11:13:00 +08:00
if ( __debugInfo ) {
if ( __debugInfo - > common . fn_flags & ZEND_ACC_STATIC ) {
2014-04-26 04:32:51 +08:00
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name - > val , __debugInfo - > common . function_name - > val ) ;
2014-02-18 11:13:00 +08:00
}
}
2011-09-13 21:29:35 +08:00
efree ( ( char * ) lc_class_name ) ;
2003-01-10 22:41:53 +08:00
}
1999-04-08 02:10:10 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2006-05-10 07:53:23 +08:00
/* count=-1 means erase all functions, otherwise,
1999-04-08 02:10:10 +08:00
* erase the first count functions
*/
2007-11-03 03:40:39 +08:00
ZEND_API void zend_unregister_functions ( const zend_function_entry * functions , int count , HashTable * function_table TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2007-09-28 02:00:48 +08:00
const zend_function_entry * ptr = functions ;
1999-04-08 02:10:10 +08:00
int i = 0 ;
1999-05-28 20:06:59 +08:00
HashTable * target_function_table = function_table ;
2014-02-10 14:04:30 +08:00
zend_string * lowercase_name ;
int fname_len ;
1999-04-08 02:10:10 +08:00
1999-05-28 20:06:59 +08:00
if ( ! target_function_table ) {
target_function_table = CG ( function_table ) ;
}
1999-04-08 02:10:10 +08:00
while ( ptr - > fname ) {
if ( count ! = - 1 & & i > = count ) {
break ;
}
2014-02-10 14:04:30 +08:00
fname_len = strlen ( ptr - > fname ) ;
2014-08-26 01:24:55 +08:00
lowercase_name = zend_string_alloc ( fname_len , 0 ) ;
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( lowercase_name - > val , ptr - > fname , fname_len ) ;
zend_hash_del ( target_function_table , lowercase_name ) ;
2014-08-26 01:24:55 +08:00
zend_string_free ( lowercase_name ) ;
1999-04-08 02:10:10 +08:00
ptr + + ;
i + + ;
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2013-12-13 03:30:45 +08:00
ZEND_API int zend_startup_module ( zend_module_entry * module TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2007-11-03 03:40:39 +08:00
if ( ( module = zend_register_internal_module ( module TSRMLS_CC ) ) ! = NULL & & zend_startup_module_ex ( module TSRMLS_CC ) = = SUCCESS ) {
2005-06-17 17:36:26 +08:00
return SUCCESS ;
}
return FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_get_module_started ( const char * module_name ) /* { { { */
2004-01-19 08:39:29 +08:00
{
zend_module_entry * module ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
module = zend_hash_str_find_ptr ( & module_registry , module_name , strlen ( module_name ) ) ;
return ( module & & module - > module_started ) ? SUCCESS : FAILURE ;
2004-01-19 08:39:29 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2004-01-19 08:39:29 +08:00
2014-05-25 19:56:51 +08:00
static int clean_module_class ( zval * el , void * arg TSRMLS_DC ) /* { { { */
2011-03-31 19:59:34 +08:00
{
2014-05-25 19:56:51 +08:00
zend_class_entry * ce = ( zend_class_entry * ) Z_PTR_P ( el ) ;
int module_number = * ( int * ) arg ;
if ( ce - > type = = ZEND_INTERNAL_CLASS & & ce - > info . internal . module - > module_number = = module_number ) {
2011-03-31 19:59:34 +08:00
return ZEND_HASH_APPLY_REMOVE ;
} else {
return ZEND_HASH_APPLY_KEEP ;
}
}
/* }}} */
static void clean_module_classes ( int module_number TSRMLS_DC ) /* { { { */
{
2014-05-25 19:56:51 +08:00
zend_hash_apply_with_argument ( EG ( class_table ) , clean_module_class , ( void * ) & module_number TSRMLS_CC ) ;
2011-03-31 19:59:34 +08:00
}
/* }}} */
2007-11-03 03:40:39 +08:00
void module_destructor ( zend_module_entry * module ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2001-07-30 09:48:22 +08:00
TSRMLS_FETCH ( ) ;
1999-04-08 02:10:10 +08:00
if ( module - > type = = MODULE_TEMPORARY ) {
2001-07-31 12:53:54 +08:00
zend_clean_module_rsrc_dtors ( module - > module_number TSRMLS_CC ) ;
2001-07-30 15:43:02 +08:00
clean_module_constants ( module - > module_number TSRMLS_CC ) ;
2011-03-31 19:59:34 +08:00
clean_module_classes ( module - > module_number TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
}
if ( module - > module_started & & module - > module_shutdown_func ) {
#if 0
2007-11-03 03:40:39 +08:00
zend_printf ( " %s: Module shutdown \n " , module - > name ) ;
1999-04-08 02:10:10 +08:00
# endif
2001-07-30 14:12:15 +08:00
module - > module_shutdown_func ( module - > type , module - > module_number TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
2006-06-15 22:03:21 +08:00
/* Deinitilaise module globals */
if ( module - > globals_size ) {
# ifdef ZTS
2012-09-15 11:50:16 +08:00
if ( * module - > globals_id_ptr ) {
ts_free_id ( * module - > globals_id_ptr ) ;
}
2006-06-15 22:03:21 +08:00
# else
if ( module - > globals_dtor ) {
module - > globals_dtor ( module - > globals_ptr TSRMLS_CC ) ;
}
# endif
}
1999-04-08 02:10:10 +08:00
module - > module_started = 0 ;
1999-05-09 20:24:21 +08:00
if ( module - > functions ) {
2001-07-30 09:48:22 +08:00
zend_unregister_functions ( module - > functions , - 1 , NULL TSRMLS_CC ) ;
1999-05-09 20:24:21 +08:00
}
1999-04-08 02:10:10 +08:00
2009-08-06 09:33:54 +08:00
# if HAVE_LIBDL
2004-09-24 23:40:22 +08:00
# if !(defined(NETWARE) && defined(APACHE_1_BUILD))
2011-07-14 20:21:15 +08:00
if ( module - > handle & & ! getenv ( " ZEND_DONT_UNLOAD_MODULES " ) ) {
2009-11-30 20:27:18 +08:00
DL_UNLOAD ( module - > handle ) ;
2006-05-10 07:53:23 +08:00
}
2004-09-22 22:31:21 +08:00
# endif
1999-04-08 02:10:10 +08:00
# endif
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2013-11-18 06:39:31 +08:00
ZEND_API void zend_activate_modules ( TSRMLS_D ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2010-07-06 19:40:17 +08:00
zend_module_entry * * p = module_request_startup_handlers ;
while ( * p ) {
zend_module_entry * module = * p ;
2001-07-27 18:10:39 +08:00
if ( module - > request_startup_func ( module - > type , module - > module_number TSRMLS_CC ) = = FAILURE ) {
1999-11-26 21:53:18 +08:00
zend_error ( E_WARNING , " request_startup() for %s module failed " , module - > name ) ;
exit ( 1 ) ;
}
2010-07-06 19:40:17 +08:00
p + + ;
1999-04-08 02:10:10 +08:00
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2005-03-16 07:46:29 +08:00
/* call request shutdown for all modules */
2014-02-17 21:59:18 +08:00
static int module_registry_cleanup ( zval * zv TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2014-02-17 21:59:18 +08:00
zend_module_entry * module = Z_PTR_P ( zv ) ;
2005-03-16 07:46:29 +08:00
if ( module - > request_shutdown_func ) {
2000-04-25 00:04:13 +08:00
#if 0
2007-11-03 03:40:39 +08:00
zend_printf ( " %s: Request shutdown \n " , module - > name ) ;
2000-04-25 00:04:13 +08:00
# endif
2005-03-16 07:46:29 +08:00
module - > request_shutdown_func ( module - > type , module - > module_number TSRMLS_CC ) ;
}
return 0 ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-03-16 07:46:29 +08:00
2013-11-18 06:39:31 +08:00
ZEND_API void zend_deactivate_modules ( TSRMLS_D ) /* { { { */
2010-07-06 19:40:17 +08:00
{
2014-07-03 03:29:53 +08:00
EG ( current_execute_data ) = NULL ; /* we're no longer executing anything */
2010-07-06 19:40:17 +08:00
zend_try {
if ( EG ( full_tables_cleanup ) ) {
2014-02-17 21:59:18 +08:00
zend_hash_reverse_apply ( & module_registry , module_registry_cleanup TSRMLS_CC ) ;
2010-07-06 19:40:17 +08:00
} else {
zend_module_entry * * p = module_request_shutdown_handlers ;
while ( * p ) {
zend_module_entry * module = * p ;
module - > request_shutdown_func ( module - > type , module - > module_number TSRMLS_CC ) ;
p + + ;
}
}
} zend_end_try ( ) ;
}
/* }}} */
ZEND_API void zend_cleanup_internal_classes ( TSRMLS_D ) /* { { { */
{
zend_class_entry * * p = class_cleanup_handlers ;
while ( * p ) {
zend_cleanup_internal_class_data ( * p TSRMLS_CC ) ;
p + + ;
}
}
/* }}} */
2008-08-13 01:20:25 +08:00
int module_registry_unload_temp ( const zend_module_entry * module TSRMLS_DC ) /* { { { */
2005-03-16 07:46:29 +08:00
{
2006-03-17 16:34:16 +08:00
return ( module - > type = = MODULE_TEMPORARY ) ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_STOP ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-05-25 18:32:35 +08:00
static int module_registry_unload_temp_wrapper ( zval * el TSRMLS_DC ) /* { { { */
2010-07-06 19:40:17 +08:00
{
2014-05-25 18:32:35 +08:00
zend_module_entry * module = ( zend_module_entry * ) Z_PTR_P ( el ) ;
return module_registry_unload_temp ( ( const zend_module_entry * ) module TSRMLS_CC ) ;
}
/* }}} */
static int exec_done_cb ( zval * el TSRMLS_DC ) /* { { { */
{
zend_module_entry * module = ( zend_module_entry * ) Z_PTR_P ( el ) ;
2010-07-06 19:40:17 +08:00
if ( module - > post_deactivate_func ) {
module - > post_deactivate_func ( ) ;
}
return 0 ;
}
/* }}} */
2013-11-18 06:39:31 +08:00
ZEND_API void zend_post_deactivate_modules ( TSRMLS_D ) /* { { { */
2010-07-06 19:40:17 +08:00
{
if ( EG ( full_tables_cleanup ) ) {
2014-05-25 18:32:35 +08:00
zend_hash_apply ( & module_registry , exec_done_cb TSRMLS_CC ) ;
zend_hash_reverse_apply ( & module_registry , module_registry_unload_temp_wrapper TSRMLS_CC ) ;
2010-07-06 19:40:17 +08:00
} else {
zend_module_entry * * p = module_post_deactivate_handlers ;
while ( * p ) {
zend_module_entry * module = * p ;
module - > post_deactivate_func ( ) ;
p + + ;
}
}
}
/* }}} */
1999-04-08 02:10:10 +08:00
/* return the next free module number */
2007-11-03 03:40:39 +08:00
int zend_next_free_module ( void ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2012-03-05 20:47:25 +08:00
return zend_hash_num_elements ( & module_registry ) + 1 ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2014-08-26 01:28:33 +08:00
static zend_class_entry * do_register_internal_class ( zend_class_entry * orig_class_entry , uint32_t ce_flags TSRMLS_DC ) /* { { { */
2003-10-23 03:59:58 +08:00
{
zend_class_entry * class_entry = malloc ( sizeof ( zend_class_entry ) ) ;
2014-08-26 01:24:55 +08:00
zend_string * lowercase_name = zend_string_alloc ( orig_class_entry - > name - > len , 1 ) ;
2003-10-23 03:59:58 +08:00
* class_entry = * orig_class_entry ;
class_entry - > type = ZEND_INTERNAL_CLASS ;
zend_initialize_class_data ( class_entry , 0 TSRMLS_CC ) ;
2014-06-17 03:32:58 +08:00
class_entry - > ce_flags = ce_flags | ZEND_ACC_CONSTANTS_UPDATED ;
2010-09-15 15:38:52 +08:00
class_entry - > info . internal . module = EG ( current_module ) ;
2003-10-23 03:59:58 +08:00
2010-09-15 15:38:52 +08:00
if ( class_entry - > info . internal . builtin_functions ) {
zend_register_functions ( class_entry , class_entry - > info . internal . builtin_functions , & class_entry - > function_table , MODULE_PERSISTENT TSRMLS_CC ) ;
2003-10-23 03:59:58 +08:00
}
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( lowercase_name - > val , orig_class_entry - > name - > val , class_entry - > name - > len ) ;
lowercase_name = zend_new_interned_string ( lowercase_name TSRMLS_CC ) ;
zend_hash_update_ptr ( CG ( class_table ) , lowercase_name , class_entry ) ;
2014-08-26 01:24:55 +08:00
zend_string_release ( lowercase_name ) ;
2003-10-23 03:59:58 +08:00
return class_entry ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-10-23 03:59:58 +08:00
2000-06-09 22:40:14 +08:00
/* If parent_ce is not NULL then it inherits from parent_ce
* If parent_ce is NULL and parent_name isn ' t then it looks for the parent and inherits from it
* If both parent_ce and parent_name are NULL it does a regular class registration
* If parent_name is specified but not found NULL is returned
*/
2014-02-10 14:04:30 +08:00
ZEND_API zend_class_entry * zend_register_internal_class_ex ( zend_class_entry * class_entry , zend_class_entry * parent_ce TSRMLS_DC ) /* { { { */
2000-06-09 22:40:14 +08:00
{
zend_class_entry * register_class ;
2001-07-30 09:48:22 +08:00
register_class = zend_register_internal_class ( class_entry TSRMLS_CC ) ;
2000-06-09 22:40:14 +08:00
if ( parent_ce ) {
2003-10-23 03:59:58 +08:00
zend_do_inheritance ( register_class , parent_ce TSRMLS_CC ) ;
2000-06-09 22:40:14 +08:00
}
return register_class ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API void zend_class_implements ( zend_class_entry * class_entry TSRMLS_DC , int num_interfaces , . . . ) /* { { { */
2003-10-15 14:24:17 +08:00
{
zend_class_entry * interface_entry ;
va_list interface_list ;
2005-02-18 04:15:40 +08:00
va_start ( interface_list , num_interfaces ) ;
2003-10-15 14:24:17 +08:00
while ( num_interfaces - - ) {
interface_entry = va_arg ( interface_list , zend_class_entry * ) ;
2006-06-07 17:21:06 +08:00
zend_do_implement_interface ( class_entry , interface_entry TSRMLS_CC ) ;
2003-10-15 14:24:17 +08:00
}
2007-11-03 03:40:39 +08:00
2003-10-15 14:24:17 +08:00
va_end ( interface_list ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-10-15 14:24:17 +08:00
2003-10-23 03:59:58 +08:00
/* A class that contains at least one abstract method automatically becomes an abstract class.
*/
2007-11-03 03:40:39 +08:00
ZEND_API zend_class_entry * zend_register_internal_class ( zend_class_entry * orig_class_entry TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2003-10-23 03:59:58 +08:00
return do_register_internal_class ( orig_class_entry , 0 TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2000-02-03 06:23:37 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API zend_class_entry * zend_register_internal_interface ( zend_class_entry * orig_class_entry TSRMLS_DC ) /* { { { */
2003-10-23 03:59:58 +08:00
{
2004-03-10 00:38:37 +08:00
return do_register_internal_class ( orig_class_entry , ZEND_ACC_INTERFACE TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-05-09 20:24:21 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_register_class_alias_ex ( const char * name , int name_len , zend_class_entry * ce TSRMLS_DC ) /* { { { */
2008-05-12 15:11:55 +08:00
{
2014-02-10 14:04:30 +08:00
zend_string * lcname ;
2008-05-12 15:11:55 +08:00
2014-02-10 14:04:30 +08:00
if ( name [ 0 ] = = ' \\ ' ) {
2014-08-26 01:24:55 +08:00
lcname = zend_string_alloc ( name_len - 1 , 1 ) ;
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( lcname - > val , name + 1 , name_len - 1 ) ;
2013-08-29 15:16:56 +08:00
} else {
2014-08-26 01:24:55 +08:00
lcname = zend_string_alloc ( name_len , 1 ) ;
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( lcname - > val , name , name_len ) ;
2013-08-29 15:16:56 +08:00
}
2014-02-21 22:19:46 +08:00
ce = zend_hash_add_ptr ( CG ( class_table ) , lcname , ce ) ;
2014-08-26 01:24:55 +08:00
zend_string_release ( lcname ) ;
2014-02-10 14:04:30 +08:00
if ( ce ) {
2008-05-12 15:11:55 +08:00
ce - > refcount + + ;
2014-02-10 14:04:30 +08:00
return SUCCESS ;
2008-05-12 15:11:55 +08:00
}
2014-02-10 14:04:30 +08:00
return FAILURE ;
2008-05-12 15:11:55 +08:00
}
/* }}} */
2008-08-13 01:20:25 +08:00
ZEND_API int zend_set_hash_symbol ( zval * symbol , const char * name , int name_length , zend_bool is_ref , int num_symbol_tables , . . . ) /* { { { */
1999-12-05 00:50:18 +08:00
{
2007-11-03 03:40:39 +08:00
HashTable * symbol_table ;
va_list symbol_table_list ;
1999-12-05 00:50:18 +08:00
2006-05-10 07:53:23 +08:00
if ( num_symbol_tables < = 0 ) return FAILURE ;
1999-12-05 00:50:18 +08:00
2014-06-05 20:04:11 +08:00
if ( is_ref ) {
ZVAL_MAKE_REF ( symbol ) ;
2014-02-10 14:04:30 +08:00
}
1999-12-05 00:50:18 +08:00
2006-05-10 07:53:23 +08:00
va_start ( symbol_table_list , num_symbol_tables ) ;
while ( num_symbol_tables - - > 0 ) {
symbol_table = va_arg ( symbol_table_list , HashTable * ) ;
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( symbol_table , name , name_length , symbol ) ;
2014-03-28 18:46:25 +08:00
if ( Z_REFCOUNTED_P ( symbol ) ) {
Z_ADDREF_P ( symbol ) ;
}
2006-05-10 07:53:23 +08:00
}
va_end ( symbol_table_list ) ;
return SUCCESS ;
1999-12-05 00:50:18 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2000-05-30 01:16:52 +08:00
/* Disabled functions support */
2007-11-03 03:40:39 +08:00
/* {{{ proto void display_disabled_function(void)
Dummy function which displays an error when a disabled function is called . */
2002-09-16 09:36:48 +08:00
ZEND_API ZEND_FUNCTION ( display_disabled_function )
2000-05-30 01:16:52 +08:00
{
2001-07-30 15:43:02 +08:00
zend_error ( E_WARNING , " %s() has been disabled for security reasons " , get_active_function_name ( TSRMLS_C ) ) ;
2000-05-30 01:16:52 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2000-05-30 01:16:52 +08:00
2007-11-03 03:40:39 +08:00
static zend_function_entry disabled_function [ ] = {
2000-05-30 01:16:52 +08:00
ZEND_FE ( display_disabled_function , NULL )
2011-08-06 09:22:27 +08:00
ZEND_FE_END
2000-05-30 01:16:52 +08:00
} ;
2007-11-03 03:40:39 +08:00
ZEND_API int zend_disable_function ( char * function_name , uint function_name_length TSRMLS_DC ) /* { { { */
2000-05-30 01:16:52 +08:00
{
2014-02-10 14:04:30 +08:00
int ret ;
ret = zend_hash_str_del ( CG ( function_table ) , function_name , function_name_length ) ;
if ( ret = = FAILURE ) {
2000-05-30 01:16:52 +08:00
return FAILURE ;
}
disabled_function [ 0 ] . fname = function_name ;
2002-11-24 04:44:12 +08:00
return zend_register_functions ( NULL , disabled_function , CG ( function_table ) , MODULE_PERSISTENT TSRMLS_CC ) ;
2000-06-06 10:47:43 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-02-01 13:01:26 +08:00
2012-08-22 17:43:12 +08:00
# ifdef ZEND_WIN32
# pragma optimize("", off)
# endif
2014-02-10 14:04:30 +08:00
static zend_object * display_disabled_class ( zend_class_entry * class_type TSRMLS_DC ) /* { { { */
2003-03-03 09:22:43 +08:00
{
zend_object * intern ;
2014-02-10 14:04:30 +08:00
intern = zend_objects_new ( class_type TSRMLS_CC ) ;
zend_error ( E_WARNING , " %s() has been disabled for security reasons " , class_type - > name - > val ) ;
return intern ;
2003-03-03 09:22:43 +08:00
}
2012-08-22 17:43:12 +08:00
# ifdef ZEND_WIN32
# pragma optimize("", on)
# endif
2007-11-03 03:40:39 +08:00
/* }}} */
2003-03-03 09:22:43 +08:00
2007-11-03 03:40:39 +08:00
static const zend_function_entry disabled_class_new [ ] = {
2011-08-06 09:22:27 +08:00
ZEND_FE_END
2003-03-03 09:22:43 +08:00
} ;
2007-11-03 03:40:39 +08:00
ZEND_API int zend_disable_class ( char * class_name , uint class_name_length TSRMLS_DC ) /* { { { */
2003-03-03 09:22:43 +08:00
{
2014-02-10 14:04:30 +08:00
zend_class_entry * disabled_class ;
zend_string * key ;
2006-05-10 07:53:23 +08:00
2014-08-26 01:24:55 +08:00
key = zend_string_alloc ( class_name_length , 0 ) ;
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( key - > val , class_name , class_name_length ) ;
disabled_class = zend_hash_find_ptr ( CG ( class_table ) , key ) ;
if ( ! disabled_class ) {
2003-03-03 09:22:43 +08:00
return FAILURE ;
}
2014-02-10 14:04:30 +08:00
INIT_CLASS_ENTRY_INIT_METHODS ( ( * disabled_class ) , disabled_class_new , NULL , NULL , NULL , NULL , NULL ) ;
disabled_class - > create_object = display_disabled_class ;
zend_hash_clean ( & disabled_class - > function_table ) ;
2006-12-21 07:01:31 +08:00
return SUCCESS ;
2003-03-03 09:22:43 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-03-03 09:22:43 +08:00
2014-02-10 14:04:30 +08:00
static int zend_is_callable_check_class ( zend_string * name , zend_fcall_info_cache * fcc , int * strict_class , char * * error TSRMLS_DC ) /* { { { */
2001-02-01 13:01:26 +08:00
{
2008-07-24 17:42:18 +08:00
int ret = 0 ;
2014-02-10 14:04:30 +08:00
zend_class_entry * ce ;
int name_len = name - > len ;
zend_string * lcname ;
2014-06-26 17:56:55 +08:00
ALLOCA_FLAG ( use_heap ) ;
2014-08-17 19:31:39 +08:00
2014-06-26 17:56:55 +08:00
STR_ALLOCA_ALLOC ( lcname , name_len , use_heap ) ;
2014-08-21 21:30:34 +08:00
zend_str_tolower_copy ( lcname - > val , name - > val , name_len ) ;
2008-07-24 17:42:18 +08:00
2009-11-30 19:39:53 +08:00
* strict_class = 0 ;
2014-08-26 04:40:58 +08:00
if ( zend_string_equals_literal ( lcname , " self " ) ) {
2008-07-24 17:42:18 +08:00
if ( ! EG ( scope ) ) {
if ( error ) * error = estrdup ( " cannot access self:: when no class scope is active " ) ;
} else {
2014-07-03 06:34:43 +08:00
fcc - > called_scope = EG ( current_execute_data ) ? EG ( current_execute_data ) - > called_scope : NULL ;
2008-07-24 17:42:18 +08:00
fcc - > calling_scope = EG ( scope ) ;
2014-03-28 06:11:22 +08:00
if ( ! fcc - > object & & Z_OBJ ( EG ( This ) ) ) {
fcc - > object = Z_OBJ ( EG ( This ) ) ;
2008-07-26 21:14:04 +08:00
}
2008-07-24 17:42:18 +08:00
ret = 1 ;
}
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lcname , " parent " ) ) {
2008-07-24 17:42:18 +08:00
if ( ! EG ( scope ) ) {
if ( error ) * error = estrdup ( " cannot access parent:: when no class scope is active " ) ;
} else if ( ! EG ( scope ) - > parent ) {
if ( error ) * error = estrdup ( " cannot access parent:: when current class scope has no parent " ) ;
} else {
2014-07-03 06:34:43 +08:00
fcc - > called_scope = EG ( current_execute_data ) ? EG ( current_execute_data ) - > called_scope : NULL ;
2008-07-24 17:42:18 +08:00
fcc - > calling_scope = EG ( scope ) - > parent ;
2014-03-28 06:11:22 +08:00
if ( ! fcc - > object & & Z_OBJ ( EG ( This ) ) ) {
fcc - > object = Z_OBJ ( EG ( This ) ) ;
2008-07-26 21:14:04 +08:00
}
2009-11-30 19:39:53 +08:00
* strict_class = 1 ;
2008-07-24 17:42:18 +08:00
ret = 1 ;
}
2014-08-26 04:40:58 +08:00
} else if ( zend_string_equals_literal ( lcname , " static " ) ) {
2014-07-03 06:34:43 +08:00
if ( ! EG ( current_execute_data ) | | ! EG ( current_execute_data ) - > called_scope ) {
2008-07-24 17:42:18 +08:00
if ( error ) * error = estrdup ( " cannot access static:: when no class scope is active " ) ;
} else {
2014-07-03 06:34:43 +08:00
fcc - > called_scope = EG ( current_execute_data ) - > called_scope ;
fcc - > calling_scope = EG ( current_execute_data ) - > called_scope ;
2014-03-28 06:11:22 +08:00
if ( ! fcc - > object & & Z_OBJ ( EG ( This ) ) ) {
fcc - > object = Z_OBJ ( EG ( This ) ) ;
2008-07-26 21:14:04 +08:00
}
2009-11-30 19:39:53 +08:00
* strict_class = 1 ;
2008-07-24 17:42:18 +08:00
ret = 1 ;
}
2014-02-10 14:04:30 +08:00
} else if ( ( ce = zend_lookup_class_ex ( name , NULL , 1 TSRMLS_CC ) ) ! = NULL ) {
2014-07-03 02:03:21 +08:00
zend_class_entry * scope ;
zend_execute_data * ex = EG ( current_execute_data ) ;
2008-07-26 21:14:04 +08:00
2014-07-03 02:03:21 +08:00
while ( ex & & ( ! ex - > func | | ! ZEND_USER_CODE ( ex - > func - > type ) ) ) {
ex = ex - > prev_execute_data ;
}
scope = ex ? ex - > func - > common . scope : NULL ;
2014-02-10 14:04:30 +08:00
fcc - > calling_scope = ce ;
2014-03-28 06:11:22 +08:00
if ( scope & & ! fcc - > object & & Z_OBJ ( EG ( This ) ) & &
2014-02-10 14:04:30 +08:00
instanceof_function ( Z_OBJCE ( EG ( This ) ) , scope TSRMLS_CC ) & &
2008-07-26 21:14:04 +08:00
instanceof_function ( scope , fcc - > calling_scope TSRMLS_CC ) ) {
2014-03-28 06:11:22 +08:00
fcc - > object = Z_OBJ ( EG ( This ) ) ;
fcc - > called_scope = Z_OBJCE ( EG ( This ) ) ;
2008-07-26 21:14:04 +08:00
} else {
2014-03-28 06:11:22 +08:00
fcc - > called_scope = fcc - > object ? zend_get_class_entry ( fcc - > object TSRMLS_CC ) : fcc - > calling_scope ;
2008-07-26 21:14:04 +08:00
}
2009-11-30 19:39:53 +08:00
* strict_class = 1 ;
2008-07-24 17:42:18 +08:00
ret = 1 ;
} else {
2014-02-22 00:53:09 +08:00
if ( error ) zend_spprintf ( error , 0 , " class '%.*s' not found " , name_len , name - > val ) ;
2008-07-24 17:42:18 +08:00
}
2014-06-26 17:56:55 +08:00
STR_ALLOCA_FREE ( lcname , use_heap ) ;
2008-07-24 17:42:18 +08:00
return ret ;
}
/* }}} */
2009-11-30 19:39:53 +08:00
static int zend_is_callable_check_func ( int check_flags , zval * callable , zend_fcall_info_cache * fcc , int strict_class , char * * error TSRMLS_DC ) /* { { { */
2008-07-24 17:42:18 +08:00
{
zend_class_entry * ce_org = fcc - > calling_scope ;
2008-07-26 21:14:04 +08:00
int retval = 0 ;
2014-02-22 03:51:08 +08:00
zend_string * mname , * cname ;
2014-02-10 14:04:30 +08:00
zend_string * lmname ;
2010-10-15 05:33:10 +08:00
const char * colon ;
2005-12-17 06:15:41 +08:00
int clen , mlen ;
2008-02-10 05:22:31 +08:00
zend_class_entry * last_scope ;
2005-12-17 06:15:41 +08:00
HashTable * ftable ;
2008-07-24 17:42:18 +08:00
int call_via_handler = 0 ;
2014-04-21 19:18:19 +08:00
ALLOCA_FLAG ( use_heap )
2006-05-10 07:53:23 +08:00
2008-02-03 06:29:41 +08:00
if ( error ) {
* error = NULL ;
}
2008-07-24 17:42:18 +08:00
fcc - > calling_scope = NULL ;
fcc - > function_handler = NULL ;
2005-12-17 06:15:41 +08:00
2007-09-29 03:52:53 +08:00
if ( ! ce_org ) {
2014-06-26 18:10:18 +08:00
zend_string * lmname ;
2014-04-21 19:18:19 +08:00
2008-11-04 23:58:55 +08:00
/* Skip leading \ */
2014-06-26 18:09:04 +08:00
if ( UNEXPECTED ( Z_STRVAL_P ( callable ) [ 0 ] = = ' \\ ' ) ) {
2014-08-26 01:24:55 +08:00
STR_ALLOCA_INIT ( lmname , Z_STRVAL_P ( callable ) + 1 , Z_STRLEN_P ( callable ) - 1 , use_heap ) ;
2007-09-29 03:52:53 +08:00
} else {
2014-06-26 18:09:04 +08:00
lmname = Z_STR_P ( callable ) ;
2007-09-29 03:52:53 +08:00
}
/* Check if function with given name exists.
2007-11-03 03:40:39 +08:00
* This may be a compound name that includes namespace name */
2014-06-26 18:09:04 +08:00
if ( EXPECTED ( ( fcc - > function_handler = zend_hash_find_ptr ( EG ( function_table ) , lmname ) ) ! = NULL ) ) {
if ( lmname ! = Z_STR_P ( callable ) ) {
STR_ALLOCA_FREE ( lmname , use_heap ) ;
}
2007-09-29 03:52:53 +08:00
return 1 ;
2014-06-26 17:56:55 +08:00
} else {
2014-06-26 18:09:04 +08:00
if ( lmname = = Z_STR_P ( callable ) ) {
2014-08-26 01:24:55 +08:00
STR_ALLOCA_INIT ( lmname , Z_STRVAL_P ( callable ) , Z_STRLEN_P ( callable ) , use_heap ) ;
2014-06-26 18:09:04 +08:00
} else {
2014-08-26 01:24:55 +08:00
zend_string_forget_hash_val ( lmname ) ;
2014-06-26 18:09:04 +08:00
}
2014-06-26 17:56:55 +08:00
zend_str_tolower ( lmname - > val , lmname - > len ) ;
if ( ( fcc - > function_handler = zend_hash_find_ptr ( EG ( function_table ) , lmname ) ) ! = NULL ) {
STR_ALLOCA_FREE ( lmname , use_heap ) ;
return 1 ;
}
2007-09-29 03:52:53 +08:00
}
2014-06-26 18:09:04 +08:00
if ( lmname ! = Z_STR_P ( callable ) ) {
STR_ALLOCA_FREE ( lmname , use_heap ) ;
2007-09-29 03:52:53 +08:00
}
}
/* Split name into class/namespace and method/function names */
2014-08-26 01:24:55 +08:00
if ( ( colon = zend_memrchr ( Z_STRVAL_P ( callable ) , ' : ' , Z_STRLEN_P ( callable ) ) ) ! = NULL & &
2007-11-03 03:40:39 +08:00
colon > Z_STRVAL_P ( callable ) & &
* ( colon - 1 ) = = ' : '
) {
2007-09-29 03:52:53 +08:00
colon - - ;
2005-12-17 06:15:41 +08:00
clen = colon - Z_STRVAL_P ( callable ) ;
2014-08-26 01:24:55 +08:00
mlen = Z_STRLEN_P ( callable ) - clen - 2 ;
2007-12-21 09:21:52 +08:00
2007-12-25 18:58:30 +08:00
if ( colon = = Z_STRVAL_P ( callable ) ) {
2008-02-02 05:27:55 +08:00
if ( error ) zend_spprintf ( error , 0 , " invalid function name " ) ;
2007-12-25 18:58:30 +08:00
return 0 ;
}
2007-09-29 03:52:53 +08:00
/* This is a compound name.
2007-11-03 03:40:39 +08:00
* Try to fetch class and then find static method . */
2008-02-10 05:22:31 +08:00
last_scope = EG ( scope ) ;
2008-02-07 04:40:19 +08:00
if ( ce_org ) {
EG ( scope ) = ce_org ;
}
2008-07-24 17:42:18 +08:00
2014-08-26 01:24:55 +08:00
cname = zend_string_init ( Z_STRVAL_P ( callable ) , clen , 0 ) ;
2014-02-22 03:51:08 +08:00
if ( ! zend_is_callable_check_class ( cname , fcc , & strict_class , error TSRMLS_CC ) ) {
2014-08-26 01:24:55 +08:00
zend_string_release ( cname ) ;
2008-07-24 17:42:18 +08:00
EG ( scope ) = last_scope ;
2005-12-17 06:15:41 +08:00
return 0 ;
}
2014-08-26 01:24:55 +08:00
zend_string_release ( cname ) ;
2008-07-24 17:42:18 +08:00
EG ( scope ) = last_scope ;
ftable = & fcc - > calling_scope - > function_table ;
if ( ce_org & & ! instanceof_function ( ce_org , fcc - > calling_scope TSRMLS_CC ) ) {
2014-02-25 20:03:34 +08:00
if ( error ) zend_spprintf ( error , 0 , " class '%s' is not a subclass of '%s' " , ce_org - > name - > val , fcc - > calling_scope - > name - > val ) ;
2005-12-17 06:15:41 +08:00
return 0 ;
}
2014-08-26 01:24:55 +08:00
mname = zend_string_init ( Z_STRVAL_P ( callable ) + clen + 2 , mlen , 0 ) ;
2007-09-29 03:52:53 +08:00
} else if ( ce_org ) {
/* Try to fetch find static method of given class. */
2014-08-26 01:24:55 +08:00
mlen = Z_STRLEN_P ( callable ) ;
2014-02-10 14:04:30 +08:00
mname = Z_STR_P ( callable ) ;
2014-08-26 01:24:55 +08:00
zend_string_addref ( mname ) ;
2007-09-29 03:52:53 +08:00
ftable = & ce_org - > function_table ;
2008-07-24 17:42:18 +08:00
fcc - > calling_scope = ce_org ;
2007-09-29 03:52:53 +08:00
} else {
/* We already checked for plain function before. */
2008-07-26 21:14:04 +08:00
if ( error & & ! ( check_flags & IS_CALLABLE_CHECK_SILENT ) ) {
zend_spprintf ( error , 0 , " function '%s' not found or invalid function name " , Z_STRVAL_P ( callable ) ) ;
}
2007-09-29 03:52:53 +08:00
return 0 ;
2005-12-17 06:15:41 +08:00
}
2014-08-26 01:24:55 +08:00
lmname = zend_string_alloc ( mlen , 0 ) ;
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( lmname - > val , mname - > val , mlen ) ;
2009-11-30 19:39:53 +08:00
if ( strict_class & &
fcc - > calling_scope & &
2014-08-26 04:40:58 +08:00
zend_string_equals_literal ( lmname , ZEND_CONSTRUCTOR_FUNC_NAME ) ) {
2009-11-30 19:39:53 +08:00
fcc - > function_handler = fcc - > calling_scope - > constructor ;
if ( fcc - > function_handler ) {
retval = 1 ;
}
2014-02-10 14:04:30 +08:00
} else if ( ( fcc - > function_handler = zend_hash_find_ptr ( ftable , lmname ) ) ! = NULL ) {
2008-07-26 21:14:04 +08:00
retval = 1 ;
2008-10-10 23:19:35 +08:00
if ( ( fcc - > function_handler - > op_array . fn_flags & ZEND_ACC_CHANGED ) & &
2012-11-20 16:51:55 +08:00
! strict_class & & EG ( scope ) & &
2008-10-10 23:19:35 +08:00
instanceof_function ( fcc - > function_handler - > common . scope , EG ( scope ) TSRMLS_CC ) ) {
zend_function * priv_fbc ;
2014-02-10 14:04:30 +08:00
if ( ( priv_fbc = zend_hash_find_ptr ( & EG ( scope ) - > function_table , lmname ) ) ! = NULL
2008-10-10 23:19:35 +08:00
& & priv_fbc - > common . fn_flags & ZEND_ACC_PRIVATE
& & priv_fbc - > common . scope = = EG ( scope ) ) {
fcc - > function_handler = priv_fbc ;
}
}
2009-01-14 19:56:08 +08:00
if ( ( check_flags & IS_CALLABLE_CHECK_NO_ACCESS ) = = 0 & &
( fcc - > calling_scope & &
2014-03-28 06:11:22 +08:00
( ( fcc - > object & & fcc - > calling_scope - > __call ) | |
( ! fcc - > object & & fcc - > calling_scope - > __callstatic ) ) ) ) {
2009-01-14 19:56:08 +08:00
if ( fcc - > function_handler - > op_array . fn_flags & ZEND_ACC_PRIVATE ) {
2014-03-28 06:11:22 +08:00
if ( ! zend_check_private ( fcc - > function_handler , fcc - > object ? zend_get_class_entry ( fcc - > object TSRMLS_CC ) : EG ( scope ) , lmname TSRMLS_CC ) ) {
2009-01-14 19:56:08 +08:00
retval = 0 ;
fcc - > function_handler = NULL ;
goto get_function_via_handler ;
}
} else if ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_PROTECTED ) {
if ( ! zend_check_protected ( fcc - > function_handler - > common . scope , EG ( scope ) ) ) {
retval = 0 ;
fcc - > function_handler = NULL ;
goto get_function_via_handler ;
}
}
}
} else {
get_function_via_handler :
2014-03-28 06:11:22 +08:00
if ( fcc - > object & & fcc - > calling_scope = = ce_org ) {
2009-11-30 19:39:53 +08:00
if ( strict_class & & ce_org - > __call ) {
fcc - > function_handler = emalloc ( sizeof ( zend_internal_function ) ) ;
fcc - > function_handler - > internal_function . type = ZEND_INTERNAL_FUNCTION ;
2010-09-15 15:38:52 +08:00
fcc - > function_handler - > internal_function . module = ( ce_org - > type = = ZEND_INTERNAL_CLASS ) ? ce_org - > info . internal . module : NULL ;
2009-11-30 19:39:53 +08:00
fcc - > function_handler - > internal_function . handler = zend_std_call_user_call ;
fcc - > function_handler - > internal_function . arg_info = NULL ;
fcc - > function_handler - > internal_function . num_args = 0 ;
fcc - > function_handler - > internal_function . scope = ce_org ;
fcc - > function_handler - > internal_function . fn_flags = ZEND_ACC_CALL_VIA_HANDLER ;
2014-02-10 14:04:30 +08:00
fcc - > function_handler - > internal_function . function_name = mname ;
2014-08-26 01:24:55 +08:00
zend_string_addref ( mname ) ;
2009-11-30 19:39:53 +08:00
call_via_handler = 1 ;
retval = 1 ;
2014-03-28 06:11:22 +08:00
} else if ( fcc - > object - > handlers - > get_method ) {
fcc - > function_handler = fcc - > object - > handlers - > get_method ( & fcc - > object , mname , NULL TSRMLS_CC ) ;
2009-01-14 19:56:08 +08:00
if ( fcc - > function_handler ) {
2009-11-30 19:39:53 +08:00
if ( strict_class & &
( ! fcc - > function_handler - > common . scope | |
! instanceof_function ( ce_org , fcc - > function_handler - > common . scope TSRMLS_CC ) ) ) {
if ( ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ! = 0 ) {
if ( fcc - > function_handler - > type ! = ZEND_OVERLOADED_FUNCTION ) {
2014-08-26 01:24:55 +08:00
zend_string_release ( fcc - > function_handler - > common . function_name ) ;
2009-11-30 19:39:53 +08:00
}
efree ( fcc - > function_handler ) ;
}
} else {
retval = 1 ;
call_via_handler = ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ! = 0 ;
}
2009-01-14 19:56:08 +08:00
}
}
} else if ( fcc - > calling_scope ) {
if ( fcc - > calling_scope - > get_static_method ) {
2014-02-10 14:04:30 +08:00
fcc - > function_handler = fcc - > calling_scope - > get_static_method ( fcc - > calling_scope , mname TSRMLS_CC ) ;
2009-01-14 19:56:08 +08:00
} else {
2014-02-10 14:04:30 +08:00
fcc - > function_handler = zend_std_get_static_method ( fcc - > calling_scope , mname , NULL TSRMLS_CC ) ;
2009-01-14 19:56:08 +08:00
}
if ( fcc - > function_handler ) {
retval = 1 ;
call_via_handler = ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ! = 0 ;
2014-03-28 06:11:22 +08:00
if ( call_via_handler & & ! fcc - > object & & Z_OBJ ( EG ( This ) ) & &
2014-02-10 14:04:30 +08:00
Z_OBJ_HT ( EG ( This ) ) - > get_class_entry & &
instanceof_function ( Z_OBJCE ( EG ( This ) ) , fcc - > calling_scope TSRMLS_CC ) ) {
2014-03-28 06:11:22 +08:00
fcc - > object = Z_OBJ ( EG ( This ) ) ;
2011-05-31 19:36:57 +08:00
}
2009-01-14 19:56:08 +08:00
}
2005-12-17 06:15:41 +08:00
}
2008-07-26 21:14:04 +08:00
}
if ( retval ) {
if ( fcc - > calling_scope & & ! call_via_handler ) {
2014-03-28 06:11:22 +08:00
if ( ! fcc - > object & & ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_ABSTRACT ) ) {
2012-09-21 17:07:14 +08:00
if ( error ) {
2014-02-22 04:31:39 +08:00
zend_spprintf ( error , 0 , " cannot call abstract method %s::%s() " , fcc - > calling_scope - > name - > val , fcc - > function_handler - > common . function_name - > val ) ;
2012-09-21 17:07:14 +08:00
retval = 0 ;
} else {
2014-02-10 14:04:30 +08:00
zend_error ( E_ERROR , " Cannot call abstract method %s::%s() " , fcc - > calling_scope - > name - > val , fcc - > function_handler - > common . function_name - > val ) ;
2012-09-21 17:07:14 +08:00
}
2014-03-28 06:11:22 +08:00
} else if ( ! fcc - > object & & ! ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_STATIC ) ) {
2008-02-02 21:56:59 +08:00
int severity ;
char * verb ;
2008-07-24 17:42:18 +08:00
if ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_ALLOW_STATIC ) {
2008-02-02 21:56:59 +08:00
severity = E_STRICT ;
verb = " should not " ;
} else {
2008-02-02 23:48:04 +08:00
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
2008-02-02 21:56:59 +08:00
severity = E_ERROR ;
verb = " cannot " ;
}
2005-12-17 06:15:41 +08:00
if ( ( check_flags & IS_CALLABLE_CHECK_IS_STATIC ) ! = 0 ) {
retval = 0 ;
2008-02-02 05:27:55 +08:00
}
2014-03-28 06:11:22 +08:00
if ( Z_OBJ ( EG ( This ) ) & & instanceof_function ( Z_OBJCE ( EG ( This ) ) , fcc - > calling_scope TSRMLS_CC ) ) {
fcc - > object = Z_OBJ ( EG ( This ) ) ;
2008-02-02 05:27:55 +08:00
if ( error ) {
2014-02-10 14:04:30 +08:00
zend_spprintf ( error , 0 , " non-static method %s::%s() %s be called statically, assuming $this from compatible context %s " , fcc - > calling_scope - > name - > val , fcc - > function_handler - > common . function_name - > val , verb , Z_OBJCE ( EG ( This ) ) - > name - > val ) ;
2009-04-02 17:56:33 +08:00
if ( severity = = E_ERROR ) {
retval = 0 ;
}
2008-02-02 05:27:55 +08:00
} else if ( retval ) {
2014-02-10 14:04:30 +08:00
zend_error ( severity , " Non-static method %s::%s() %s be called statically, assuming $this from compatible context %s " , fcc - > calling_scope - > name - > val , fcc - > function_handler - > common . function_name - > val , verb , Z_OBJCE ( EG ( This ) ) - > name - > val ) ;
2008-02-02 05:27:55 +08:00
}
} else {
if ( error ) {
2014-02-10 14:04:30 +08:00
zend_spprintf ( error , 0 , " non-static method %s::%s() %s be called statically " , fcc - > calling_scope - > name - > val , fcc - > function_handler - > common . function_name - > val , verb ) ;
2009-04-02 17:56:33 +08:00
if ( severity = = E_ERROR ) {
retval = 0 ;
}
2008-02-02 05:27:55 +08:00
} else if ( retval ) {
2014-02-10 14:04:30 +08:00
zend_error ( severity , " Non-static method %s::%s() %s be called statically " , fcc - > calling_scope - > name - > val , fcc - > function_handler - > common . function_name - > val , verb ) ;
2006-01-14 23:22:40 +08:00
}
2005-12-17 06:15:41 +08:00
}
}
if ( retval & & ( check_flags & IS_CALLABLE_CHECK_NO_ACCESS ) = = 0 ) {
2008-07-24 17:42:18 +08:00
if ( fcc - > function_handler - > op_array . fn_flags & ZEND_ACC_PRIVATE ) {
2014-03-28 06:11:22 +08:00
if ( ! zend_check_private ( fcc - > function_handler , fcc - > object ? zend_get_class_entry ( fcc - > object TSRMLS_CC ) : EG ( scope ) , lmname TSRMLS_CC ) ) {
2008-02-03 06:29:41 +08:00
if ( error ) {
if ( * error ) {
efree ( * error ) ;
}
2014-02-22 04:31:39 +08:00
zend_spprintf ( error , 0 , " cannot access private method %s::%s() " , fcc - > calling_scope - > name - > val , fcc - > function_handler - > common . function_name - > val ) ;
2008-02-03 06:29:41 +08:00
}
2005-12-17 06:15:41 +08:00
retval = 0 ;
}
2008-07-24 17:42:18 +08:00
} else if ( ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_PROTECTED ) ) {
if ( ! zend_check_protected ( fcc - > function_handler - > common . scope , EG ( scope ) ) ) {
2008-02-03 06:29:41 +08:00
if ( error ) {
if ( * error ) {
efree ( * error ) ;
}
2014-02-22 04:31:39 +08:00
zend_spprintf ( error , 0 , " cannot access protected method %s::%s() " , fcc - > calling_scope - > name - > val , fcc - > function_handler - > common . function_name - > val ) ;
2008-02-03 06:29:41 +08:00
}
2005-12-17 06:15:41 +08:00
retval = 0 ;
}
}
}
}
2008-07-26 21:14:04 +08:00
} else if ( error & & ! ( check_flags & IS_CALLABLE_CHECK_SILENT ) ) {
if ( fcc - > calling_scope ) {
2014-02-22 03:51:08 +08:00
if ( error ) zend_spprintf ( error , 0 , " class '%s' does not have a method '%s' " , fcc - > calling_scope - > name - > val , mname - > val ) ;
2008-07-26 21:14:04 +08:00
} else {
2014-02-22 03:51:08 +08:00
if ( error ) zend_spprintf ( error , 0 , " function '%s' does not exist " , mname - > val ) ;
2008-07-26 21:14:04 +08:00
}
2005-12-17 06:15:41 +08:00
}
2014-08-26 01:24:55 +08:00
zend_string_free ( lmname ) ;
zend_string_release ( mname ) ;
2008-08-07 20:04:14 +08:00
2014-03-28 06:11:22 +08:00
if ( fcc - > object ) {
fcc - > called_scope = zend_get_class_entry ( fcc - > object TSRMLS_CC ) ;
2008-07-24 17:42:18 +08:00
}
2008-07-26 21:14:04 +08:00
if ( retval ) {
2008-07-24 17:42:18 +08:00
fcc - > initialized = 1 ;
}
2005-12-17 06:15:41 +08:00
return retval ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-12-17 06:15:41 +08:00
2014-03-28 06:11:22 +08:00
ZEND_API zend_bool zend_is_callable_ex ( zval * callable , zend_object * object , uint check_flags , zend_string * * callable_name , zend_fcall_info_cache * fcc , char * * error TSRMLS_DC ) /* { { { */
2005-12-17 06:15:41 +08:00
{
2008-07-26 21:14:04 +08:00
zend_bool ret ;
2008-07-24 17:42:18 +08:00
zend_fcall_info_cache fcc_local ;
2005-07-29 04:55:50 +08:00
2006-03-23 21:14:55 +08:00
if ( callable_name ) {
* callable_name = NULL ;
}
2008-07-24 17:42:18 +08:00
if ( fcc = = NULL ) {
fcc = & fcc_local ;
2005-07-29 04:55:50 +08:00
}
2008-02-02 05:27:55 +08:00
if ( error ) {
* error = NULL ;
}
2008-07-24 17:42:18 +08:00
fcc - > initialized = 0 ;
fcc - > calling_scope = NULL ;
fcc - > called_scope = NULL ;
fcc - > function_handler = NULL ;
fcc - > calling_scope = NULL ;
2014-03-28 06:11:22 +08:00
fcc - > object = NULL ;
2001-02-01 13:01:26 +08:00
2014-03-28 06:11:22 +08:00
if ( object & &
2014-02-12 22:08:11 +08:00
( ! EG ( objects_store ) . object_buckets | |
2014-04-09 05:50:15 +08:00
! IS_OBJ_VALID ( EG ( objects_store ) . object_buckets [ object - > handle ] ) ) ) {
2014-02-12 22:08:11 +08:00
return 0 ;
}
2008-07-27 02:32:20 +08:00
2001-03-12 11:08:28 +08:00
switch ( Z_TYPE_P ( callable ) ) {
2001-02-01 13:01:26 +08:00
case IS_STRING :
2014-03-28 06:11:22 +08:00
if ( object ) {
fcc - > object = object ;
fcc - > calling_scope = zend_get_class_entry ( object TSRMLS_CC ) ;
2008-07-26 21:14:04 +08:00
if ( callable_name ) {
char * ptr ;
2014-08-26 01:24:55 +08:00
* callable_name = zend_string_alloc ( fcc - > calling_scope - > name - > len + Z_STRLEN_P ( callable ) + sizeof ( " :: " ) - 1 , 0 ) ;
2014-02-25 20:03:34 +08:00
ptr = ( * callable_name ) - > val ;
memcpy ( ptr , fcc - > calling_scope - > name - > val , fcc - > calling_scope - > name - > len ) ;
2014-02-10 14:04:30 +08:00
ptr + = fcc - > calling_scope - > name - > len ;
2008-07-26 21:14:04 +08:00
memcpy ( ptr , " :: " , sizeof ( " :: " ) - 1 ) ;
ptr + = sizeof ( " :: " ) - 1 ;
2014-08-26 01:24:55 +08:00
memcpy ( ptr , Z_STRVAL_P ( callable ) , Z_STRLEN_P ( callable ) + 1 ) ;
2008-07-26 21:14:04 +08:00
}
} else if ( callable_name ) {
2014-08-26 01:24:55 +08:00
* callable_name = zend_string_copy ( Z_STR_P ( callable ) ) ;
2003-12-29 00:20:06 +08:00
}
2005-04-27 23:45:36 +08:00
if ( check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY ) {
2008-07-26 21:14:04 +08:00
fcc - > called_scope = fcc - > calling_scope ;
2001-03-12 11:08:28 +08:00
return 1 ;
2003-12-29 00:20:06 +08:00
}
2007-11-03 03:40:39 +08:00
2009-11-30 19:39:53 +08:00
ret = zend_is_callable_check_func ( check_flags , callable , fcc , 0 , error TSRMLS_CC ) ;
2008-07-26 21:14:04 +08:00
if ( fcc = = & fcc_local & &
fcc - > function_handler & &
( ( fcc - > function_handler - > type = = ZEND_INTERNAL_FUNCTION & &
( fcc - > function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ) | |
fcc - > function_handler - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY | |
fcc - > function_handler - > type = = ZEND_OVERLOADED_FUNCTION ) ) {
if ( fcc - > function_handler - > type ! = ZEND_OVERLOADED_FUNCTION ) {
2014-08-26 01:24:55 +08:00
zend_string_release ( fcc - > function_handler - > common . function_name ) ;
2008-07-26 21:14:04 +08:00
}
efree ( fcc - > function_handler ) ;
}
return ret ;
2001-02-01 13:01:26 +08:00
case IS_ARRAY :
{
2014-02-10 14:04:30 +08:00
zval * method = NULL ;
zval * obj = NULL ;
2009-11-30 19:39:53 +08:00
int strict_class = 0 ;
2006-05-10 07:53:23 +08:00
2008-02-02 05:27:55 +08:00
if ( zend_hash_num_elements ( Z_ARRVAL_P ( callable ) ) = = 2 ) {
2014-02-10 14:04:30 +08:00
obj = zend_hash_index_find ( Z_ARRVAL_P ( callable ) , 0 ) ;
method = zend_hash_index_find ( Z_ARRVAL_P ( callable ) , 1 ) ;
2008-02-02 05:27:55 +08:00
}
2001-03-12 11:08:28 +08:00
2014-03-07 17:08:14 +08:00
do {
if ( obj = = NULL | | method = = NULL ) {
break ;
2014-03-05 17:29:29 +08:00
}
2014-03-07 17:08:14 +08:00
2014-03-27 17:39:09 +08:00
ZVAL_DEREF ( method ) ;
2014-03-07 17:08:14 +08:00
if ( Z_TYPE_P ( method ) ! = IS_STRING ) {
break ;
}
2014-03-27 17:39:09 +08:00
ZVAL_DEREF ( obj ) ;
2014-02-10 14:04:30 +08:00
if ( Z_TYPE_P ( obj ) = = IS_STRING ) {
2001-05-10 04:07:49 +08:00
if ( callable_name ) {
char * ptr ;
2014-02-25 20:03:34 +08:00
2014-08-26 01:24:55 +08:00
* callable_name = zend_string_alloc ( Z_STRLEN_P ( obj ) + Z_STRLEN_P ( method ) + sizeof ( " :: " ) - 1 , 0 ) ;
2014-02-25 20:03:34 +08:00
ptr = ( * callable_name ) - > val ;
2014-08-26 01:24:55 +08:00
memcpy ( ptr , Z_STRVAL_P ( obj ) , Z_STRLEN_P ( obj ) ) ;
ptr + = Z_STRLEN_P ( obj ) ;
2001-05-10 04:07:49 +08:00
memcpy ( ptr , " :: " , sizeof ( " :: " ) - 1 ) ;
ptr + = sizeof ( " :: " ) - 1 ;
2014-08-26 01:24:55 +08:00
memcpy ( ptr , Z_STRVAL_P ( method ) , Z_STRLEN_P ( method ) + 1 ) ;
2005-10-13 17:48:38 +08:00
}
2001-05-10 04:07:49 +08:00
2005-10-26 07:19:59 +08:00
if ( check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY ) {
2001-05-10 04:07:49 +08:00
return 1 ;
2005-10-26 07:19:59 +08:00
}
2001-05-10 04:07:49 +08:00
2014-02-10 14:04:30 +08:00
if ( ! zend_is_callable_check_class ( Z_STR_P ( obj ) , fcc , & strict_class , error TSRMLS_CC ) ) {
2008-07-24 17:42:18 +08:00
return 0 ;
2002-03-12 18:08:47 +08:00
}
2008-07-24 17:42:18 +08:00
2014-03-07 17:08:14 +08:00
} else if ( Z_TYPE_P ( obj ) = = IS_OBJECT ) {
2014-02-21 21:39:02 +08:00
if ( ! EG ( objects_store ) . object_buckets | |
2014-04-09 05:50:15 +08:00
! IS_OBJ_VALID ( EG ( objects_store ) . object_buckets [ Z_OBJ_HANDLE_P ( obj ) ] ) ) {
2014-02-12 22:08:11 +08:00
return 0 ;
}
2008-07-27 02:32:20 +08:00
2014-02-10 14:04:30 +08:00
fcc - > calling_scope = Z_OBJCE_P ( obj ) ; /* TBFixed: what if it's overloaded? */
2006-05-10 07:53:23 +08:00
2014-03-28 06:11:22 +08:00
fcc - > object = Z_OBJ_P ( obj ) ;
2001-05-10 04:07:49 +08:00
if ( callable_name ) {
char * ptr ;
2014-08-26 01:24:55 +08:00
* callable_name = zend_string_alloc ( fcc - > calling_scope - > name - > len + Z_STRLEN_P ( method ) + sizeof ( " :: " ) - 1 , 0 ) ;
2014-02-25 20:03:34 +08:00
ptr = ( * callable_name ) - > val ;
memcpy ( ptr , fcc - > calling_scope - > name - > val , fcc - > calling_scope - > name - > len ) ;
2014-02-10 14:04:30 +08:00
ptr + = fcc - > calling_scope - > name - > len ;
2001-05-10 04:07:49 +08:00
memcpy ( ptr , " :: " , sizeof ( " :: " ) - 1 ) ;
ptr + = sizeof ( " :: " ) - 1 ;
2014-08-26 01:24:55 +08:00
memcpy ( ptr , Z_STRVAL_P ( method ) , Z_STRLEN_P ( method ) + 1 ) ;
2001-05-10 04:07:49 +08:00
}
2005-10-26 07:19:59 +08:00
if ( check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY ) {
2008-07-24 17:42:18 +08:00
fcc - > called_scope = fcc - > calling_scope ;
2001-05-10 04:07:49 +08:00
return 1 ;
2005-10-26 07:19:59 +08:00
}
2014-03-07 17:08:14 +08:00
} else {
break ;
2001-03-13 00:27:26 +08:00
}
2001-05-10 04:07:49 +08:00
2014-02-10 14:04:30 +08:00
ret = zend_is_callable_check_func ( check_flags , method , fcc , strict_class , error TSRMLS_CC ) ;
2008-07-26 21:14:04 +08:00
if ( fcc = = & fcc_local & &
fcc - > function_handler & &
( ( fcc - > function_handler - > type = = ZEND_INTERNAL_FUNCTION & &
( fcc - > function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ) | |
fcc - > function_handler - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY | |
fcc - > function_handler - > type = = ZEND_OVERLOADED_FUNCTION ) ) {
if ( fcc - > function_handler - > type ! = ZEND_OVERLOADED_FUNCTION ) {
2014-08-26 01:24:55 +08:00
zend_string_release ( fcc - > function_handler - > common . function_name ) ;
2008-07-26 21:14:04 +08:00
}
efree ( fcc - > function_handler ) ;
}
return ret ;
2014-03-07 17:08:14 +08:00
} while ( 0 ) ;
if ( zend_hash_num_elements ( Z_ARRVAL_P ( callable ) ) = = 2 ) {
if ( ! obj | | ( ! Z_ISREF_P ( obj ) ?
( Z_TYPE_P ( obj ) ! = IS_STRING & & Z_TYPE_P ( obj ) ! = IS_OBJECT ) :
( Z_TYPE_P ( Z_REFVAL_P ( obj ) ) ! = IS_STRING & & Z_TYPE_P ( Z_REFVAL_P ( obj ) ) ! = IS_OBJECT ) ) ) {
if ( error ) zend_spprintf ( error , 0 , " first array member is not a valid class name or object " ) ;
2008-02-02 05:27:55 +08:00
} else {
2014-03-07 17:08:14 +08:00
if ( error ) zend_spprintf ( error , 0 , " second array member is not a valid method " ) ;
2001-03-12 11:08:28 +08:00
}
2014-03-07 17:08:14 +08:00
} else {
if ( error ) zend_spprintf ( error , 0 , " array must have exactly two members " ) ;
}
if ( callable_name ) {
2014-08-26 01:24:55 +08:00
* callable_name = zend_string_init ( " Array " , sizeof ( " Array " ) - 1 , 0 ) ;
2003-07-03 17:18:41 +08:00
}
2001-02-01 13:01:26 +08:00
}
2007-11-03 03:40:39 +08:00
return 0 ;
2001-02-01 13:01:26 +08:00
2008-07-14 17:49:03 +08:00
case IS_OBJECT :
2014-03-05 05:54:21 +08:00
if ( Z_OBJ_HANDLER_P ( callable , get_closure ) & & Z_OBJ_HANDLER_P ( callable , get_closure ) ( callable , & fcc - > calling_scope , & fcc - > function_handler , & fcc - > object TSRMLS_CC ) = = SUCCESS ) {
2008-07-24 17:42:18 +08:00
fcc - > called_scope = fcc - > calling_scope ;
2008-07-14 17:49:03 +08:00
if ( callable_name ) {
2008-07-14 20:18:23 +08:00
zend_class_entry * ce = Z_OBJCE_P ( callable ) ; /* TBFixed: what if it's overloaded? */
2014-08-26 01:24:55 +08:00
* callable_name = zend_string_alloc ( ce - > name - > len + sizeof ( " ::__invoke " ) - 1 , 0 ) ;
2014-02-25 20:03:34 +08:00
memcpy ( ( * callable_name ) - > val , ce - > name - > val , ce - > name - > len ) ;
memcpy ( ( * callable_name ) - > val + ce - > name - > len , " ::__invoke " , sizeof ( " ::__invoke " ) ) ;
2008-07-14 17:49:03 +08:00
}
return 1 ;
}
/* break missing intentionally */
2001-02-01 13:01:26 +08:00
default :
2001-03-12 11:08:28 +08:00
if ( callable_name ) {
2014-04-21 23:51:15 +08:00
* callable_name = zval_get_string ( callable ) ;
2001-03-12 11:08:28 +08:00
}
2008-02-02 05:27:55 +08:00
if ( error ) zend_spprintf ( error , 0 , " no array or string given " ) ;
2007-11-03 03:40:39 +08:00
return 0 ;
2001-02-01 13:01:26 +08:00
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-10-13 02:40:30 +08:00
2014-02-25 20:03:34 +08:00
ZEND_API zend_bool zend_is_callable ( zval * callable , uint check_flags , zend_string * * callable_name TSRMLS_DC ) /* { { { */
2005-07-29 04:55:50 +08:00
{
2014-02-25 20:03:34 +08:00
return zend_is_callable_ex ( callable , NULL , check_flags , callable_name , NULL , NULL TSRMLS_CC ) ;
2005-07-29 04:55:50 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-07-29 04:55:50 +08:00
2014-02-25 20:03:34 +08:00
ZEND_API zend_bool zend_make_callable ( zval * callable , zend_string * * callable_name TSRMLS_DC ) /* { { { */
2003-10-26 06:58:06 +08:00
{
2008-07-24 17:42:18 +08:00
zend_fcall_info_cache fcc ;
2005-11-04 07:45:18 +08:00
2014-02-25 20:03:34 +08:00
if ( zend_is_callable_ex ( callable , NULL , IS_CALLABLE_STRICT , callable_name , & fcc , NULL TSRMLS_CC ) ) {
2008-07-24 17:42:18 +08:00
if ( Z_TYPE_P ( callable ) = = IS_STRING & & fcc . calling_scope ) {
2005-11-04 07:45:18 +08:00
zval_dtor ( callable ) ;
array_init ( callable ) ;
2014-08-26 01:24:55 +08:00
add_next_index_str ( callable , zend_string_copy ( fcc . calling_scope - > name ) ) ;
add_next_index_str ( callable , zend_string_copy ( fcc . function_handler - > common . function_name ) ) ;
2005-11-04 07:45:18 +08:00
}
2008-07-26 21:14:04 +08:00
if ( fcc . function_handler & &
( ( fcc . function_handler - > type = = ZEND_INTERNAL_FUNCTION & &
( fcc . function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ) | |
fcc . function_handler - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY | |
fcc . function_handler - > type = = ZEND_OVERLOADED_FUNCTION ) ) {
if ( fcc . function_handler - > type ! = ZEND_OVERLOADED_FUNCTION ) {
2014-08-26 01:24:55 +08:00
zend_string_release ( fcc . function_handler - > common . function_name ) ;
2008-07-26 21:14:04 +08:00
}
efree ( fcc . function_handler ) ;
}
2003-10-26 06:58:06 +08:00
return 1 ;
}
2005-11-04 07:45:18 +08:00
return 0 ;
2003-10-26 06:58:06 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-10-26 06:58:06 +08:00
2014-02-25 20:03:34 +08:00
ZEND_API int zend_fcall_info_init ( zval * callable , uint check_flags , zend_fcall_info * fci , zend_fcall_info_cache * fcc , zend_string * * callable_name , char * * error TSRMLS_DC ) /* { { { */
2006-06-07 17:43:54 +08:00
{
2014-02-25 20:03:34 +08:00
if ( ! zend_is_callable_ex ( callable , NULL , check_flags , callable_name , fcc , error TSRMLS_CC ) ) {
2006-06-07 17:43:54 +08:00
return FAILURE ;
}
fci - > size = sizeof ( * fci ) ;
2008-07-24 17:42:18 +08:00
fci - > function_table = fcc - > calling_scope ? & fcc - > calling_scope - > function_table : EG ( function_table ) ;
2014-03-28 06:11:22 +08:00
fci - > object = fcc - > object ;
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( & fci - > function_name , callable ) ;
fci - > retval = NULL ;
2006-06-07 17:43:54 +08:00
fci - > param_count = 0 ;
fci - > params = NULL ;
fci - > no_separation = 1 ;
fci - > symbol_table = NULL ;
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2006-06-07 17:43:54 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API void zend_fcall_info_args_clear ( zend_fcall_info * fci , int free_mem ) /* { { { */
2006-06-07 17:43:54 +08:00
{
if ( fci - > params ) {
2014-03-12 02:33:28 +08:00
int i ;
for ( i = 0 ; i < fci - > param_count ; i + + ) {
zval_ptr_dtor ( & fci - > params [ i ] ) ;
}
2007-04-06 03:49:42 +08:00
if ( free_mem ) {
efree ( fci - > params ) ;
fci - > params = NULL ;
}
2006-06-07 17:43:54 +08:00
}
fci - > param_count = 0 ;
2007-04-06 03:49:42 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2007-04-06 03:49:42 +08:00
2014-02-10 14:04:30 +08:00
ZEND_API void zend_fcall_info_args_save ( zend_fcall_info * fci , int * param_count , zval * * params ) /* { { { */
2007-04-06 03:49:42 +08:00
{
* param_count = fci - > param_count ;
* params = fci - > params ;
fci - > param_count = 0 ;
fci - > params = NULL ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2007-04-06 03:49:42 +08:00
2014-02-10 14:04:30 +08:00
ZEND_API void zend_fcall_info_args_restore ( zend_fcall_info * fci , int param_count , zval * params ) /* { { { */
2007-04-06 03:49:42 +08:00
{
zend_fcall_info_args_clear ( fci , 1 ) ;
fci - > param_count = param_count ;
fci - > params = params ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2007-04-06 03:49:42 +08:00
2014-08-21 03:28:32 +08:00
ZEND_API int zend_fcall_info_args_ex ( zend_fcall_info * fci , zend_function * func , zval * args TSRMLS_DC ) /* { { { */
2007-04-06 03:49:42 +08:00
{
2014-02-10 14:04:30 +08:00
zval * arg , * params ;
2014-08-21 03:28:32 +08:00
int n = 1 ;
2007-04-06 03:49:42 +08:00
zend_fcall_info_args_clear ( fci , ! args ) ;
2006-06-07 17:43:54 +08:00
if ( ! args ) {
return SUCCESS ;
}
if ( Z_TYPE_P ( args ) ! = IS_ARRAY ) {
return FAILURE ;
}
fci - > param_count = zend_hash_num_elements ( Z_ARRVAL_P ( args ) ) ;
2014-02-10 14:04:30 +08:00
fci - > params = params = ( zval * ) erealloc ( fci - > params , fci - > param_count * sizeof ( zval ) ) ;
2006-06-07 17:43:54 +08:00
2014-04-18 23:18:11 +08:00
ZEND_HASH_FOREACH_VAL ( Z_ARRVAL_P ( args ) , arg ) {
2014-08-21 03:28:32 +08:00
if ( func & & ! Z_ISREF_P ( arg ) & & ARG_SHOULD_BE_SENT_BY_REF ( func , n ) ) {
ZVAL_NEW_REF ( params , arg ) ;
if ( Z_REFCOUNTED_P ( arg ) ) {
Z_ADDREF_P ( arg ) ;
}
} else {
ZVAL_COPY ( params , arg ) ;
}
2014-02-10 14:04:30 +08:00
params + + ;
2014-08-21 03:28:32 +08:00
n + + ;
2014-04-18 23:18:11 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2007-11-03 03:40:39 +08:00
return SUCCESS ;
}
/* }}} */
2014-08-21 03:28:32 +08:00
ZEND_API int zend_fcall_info_args ( zend_fcall_info * fci , zval * args TSRMLS_DC ) /* { { { */
{
return zend_fcall_info_args_ex ( fci , NULL , args TSRMLS_CC ) ;
}
/* }}} */
2014-02-10 14:04:30 +08:00
ZEND_API int zend_fcall_info_argp ( zend_fcall_info * fci TSRMLS_DC , int argc , zval * argv ) /* { { { */
2007-11-03 03:40:39 +08:00
{
int i ;
if ( argc < 0 ) {
return FAILURE ;
}
zend_fcall_info_args_clear ( fci , ! argc ) ;
if ( argc ) {
fci - > param_count = argc ;
2014-02-10 14:04:30 +08:00
fci - > params = ( zval * ) erealloc ( fci - > params , fci - > param_count * sizeof ( zval ) ) ;
2007-11-03 03:40:39 +08:00
for ( i = 0 ; i < argc ; + + i ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( & fci - > params [ i ] , & argv [ i ] ) ;
2007-11-03 03:40:39 +08:00
}
}
return SUCCESS ;
}
/* }}} */
ZEND_API int zend_fcall_info_argv ( zend_fcall_info * fci TSRMLS_DC , int argc , va_list * argv ) /* { { { */
{
int i ;
2014-02-10 14:04:30 +08:00
zval * arg ;
2007-11-03 03:40:39 +08:00
if ( argc < 0 ) {
return FAILURE ;
}
zend_fcall_info_args_clear ( fci , ! argc ) ;
if ( argc ) {
fci - > param_count = argc ;
2014-02-10 14:04:30 +08:00
fci - > params = ( zval * ) erealloc ( fci - > params , fci - > param_count * sizeof ( zval ) ) ;
2007-11-03 03:40:39 +08:00
for ( i = 0 ; i < argc ; + + i ) {
2014-02-10 14:04:30 +08:00
arg = va_arg ( * argv , zval * ) ;
ZVAL_COPY_VALUE ( & fci - > params [ i ] , arg ) ;
2007-11-03 03:40:39 +08:00
}
}
2006-06-07 17:43:54 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
ZEND_API int zend_fcall_info_argn ( zend_fcall_info * fci TSRMLS_DC , int argc , . . . ) /* { { { */
{
int ret ;
va_list argv ;
2006-06-07 17:43:54 +08:00
2007-11-03 03:40:39 +08:00
va_start ( argv , argc ) ;
ret = zend_fcall_info_argv ( fci TSRMLS_CC , argc , & argv ) ;
va_end ( argv ) ;
return ret ;
}
/* }}} */
2006-06-07 17:43:54 +08:00
2014-02-10 14:04:30 +08:00
ZEND_API int zend_fcall_info_call ( zend_fcall_info * fci , zend_fcall_info_cache * fcc , zval * retval_ptr , zval * args TSRMLS_DC ) /* { { { */
2006-06-07 17:43:54 +08:00
{
2014-02-10 14:04:30 +08:00
zval retval , * org_params = NULL ;
2007-11-03 03:40:39 +08:00
int result , org_count = 0 ;
2006-06-07 17:43:54 +08:00
2014-02-10 14:04:30 +08:00
fci - > retval = retval_ptr ? retval_ptr : & retval ;
2006-06-07 17:43:54 +08:00
if ( args ) {
2007-04-06 03:49:42 +08:00
zend_fcall_info_args_save ( fci , & org_count , & org_params ) ;
2006-06-07 17:43:54 +08:00
zend_fcall_info_args ( fci , args TSRMLS_CC ) ;
}
result = zend_call_function ( fci , fcc TSRMLS_CC ) ;
2007-11-03 03:40:39 +08:00
2014-02-10 14:04:30 +08:00
if ( ! retval_ptr & & Z_TYPE ( retval ) ! = IS_UNDEF ) {
2006-06-07 17:43:54 +08:00
zval_ptr_dtor ( & retval ) ;
}
if ( args ) {
2007-04-06 03:49:42 +08:00
zend_fcall_info_args_restore ( fci , org_count , org_params ) ;
2006-06-07 17:43:54 +08:00
}
return result ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2006-06-07 17:43:54 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API const char * zend_get_module_version ( const char * module_name ) /* { { { */
2001-10-13 02:40:30 +08:00
{
2014-02-10 14:04:30 +08:00
zend_string * lname ;
2007-05-17 02:57:15 +08:00
int name_len = strlen ( module_name ) ;
2001-10-13 02:40:30 +08:00
zend_module_entry * module ;
2014-08-26 01:24:55 +08:00
lname = zend_string_alloc ( name_len , 0 ) ;
2014-02-10 14:04:30 +08:00
zend_str_tolower_copy ( lname - > val , module_name , name_len ) ;
module = zend_hash_find_ptr ( & module_registry , lname ) ;
2014-08-26 01:24:55 +08:00
zend_string_free ( lname ) ;
2014-02-10 14:04:30 +08:00
return module ? module - > version : NULL ;
2001-10-13 02:40:30 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-02-01 09:49:15 +08:00
2014-02-10 14:04:30 +08:00
ZEND_API int zend_declare_property_ex ( zend_class_entry * ce , zend_string * name , zval * property , int access_type , zend_string * doc_comment TSRMLS_DC ) /* { { { */
2003-07-07 03:55:20 +08:00
{
2014-06-18 06:47:01 +08:00
zend_property_info * property_info , * property_info_ptr ;
if ( ce - > type = = ZEND_INTERNAL_CLASS ) {
property_info = pemalloc ( sizeof ( zend_property_info ) , 1 ) ;
} else {
property_info = zend_arena_alloc ( & CG ( arena ) , sizeof ( zend_property_info ) ) ;
}
2003-07-07 03:55:20 +08:00
2014-06-17 03:32:58 +08:00
if ( Z_CONSTANT_P ( property ) ) {
ce - > ce_flags & = ~ ZEND_ACC_CONSTANTS_UPDATED ;
}
2003-07-07 03:55:20 +08:00
if ( ! ( access_type & ZEND_ACC_PPP_MASK ) ) {
access_type | = ZEND_ACC_PUBLIC ;
}
if ( access_type & ZEND_ACC_STATIC ) {
2014-02-10 14:04:30 +08:00
if ( ( property_info_ptr = zend_hash_find_ptr ( & ce - > properties_info , name ) ) ! = NULL & &
2010-05-24 22:11:39 +08:00
( property_info_ptr - > flags & ZEND_ACC_STATIC ) ! = 0 ) {
2014-06-18 06:47:01 +08:00
property_info - > offset = property_info_ptr - > offset ;
zval_ptr_dtor ( & ce - > default_static_members_table [ property_info - > offset ] ) ;
2014-02-10 14:04:30 +08:00
zend_hash_del ( & ce - > properties_info , name ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-06-18 06:47:01 +08:00
property_info - > offset = ce - > default_static_members_count + + ;
2014-02-10 14:04:30 +08:00
ce - > default_static_members_table = perealloc ( ce - > default_static_members_table , sizeof ( zval ) * ce - > default_static_members_count , ce - > type = = ZEND_INTERNAL_CLASS ) ;
2010-05-24 22:11:39 +08:00
}
2014-06-18 06:47:01 +08:00
ZVAL_COPY_VALUE ( & ce - > default_static_members_table [ property_info - > offset ] , property ) ;
2010-05-24 22:11:39 +08:00
if ( ce - > type = = ZEND_USER_CLASS ) {
ce - > static_members_table = ce - > default_static_members_table ;
}
2003-07-07 03:55:20 +08:00
} else {
2014-02-10 14:04:30 +08:00
if ( ( property_info_ptr = zend_hash_find_ptr ( & ce - > properties_info , name ) ) ! = NULL & &
2010-05-24 22:11:39 +08:00
( property_info_ptr - > flags & ZEND_ACC_STATIC ) = = 0 ) {
2014-06-18 06:47:01 +08:00
property_info - > offset = property_info_ptr - > offset ;
zval_ptr_dtor ( & ce - > default_properties_table [ property_info - > offset ] ) ;
2014-02-10 14:04:30 +08:00
zend_hash_del ( & ce - > properties_info , name ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-06-18 06:47:01 +08:00
property_info - > offset = ce - > default_properties_count + + ;
2014-02-10 14:04:30 +08:00
ce - > default_properties_table = perealloc ( ce - > default_properties_table , sizeof ( zval ) * ce - > default_properties_count , ce - > type = = ZEND_INTERNAL_CLASS ) ;
2010-05-24 22:11:39 +08:00
}
2014-06-18 06:47:01 +08:00
ZVAL_COPY_VALUE ( & ce - > default_properties_table [ property_info - > offset ] , property ) ;
2003-07-07 03:55:20 +08:00
}
2003-08-25 06:45:59 +08:00
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
switch ( Z_TYPE_P ( property ) ) {
case IS_ARRAY :
case IS_OBJECT :
case IS_RESOURCE :
zend_error ( E_CORE_ERROR , " Internal zval's can't be arrays, objects or resources " ) ;
break ;
default :
break ;
}
2003-08-25 01:32:47 +08:00
}
2003-07-07 03:55:20 +08:00
switch ( access_type & ZEND_ACC_PPP_MASK ) {
2003-07-08 00:22:56 +08:00
case ZEND_ACC_PRIVATE : {
2014-06-18 06:47:01 +08:00
property_info - > name = zend_mangle_property_name ( ce - > name - > val , ce - > name - > len , name - > val , name - > len , ce - > type & ZEND_INTERNAL_CLASS ) ;
2003-07-08 00:22:56 +08:00
}
break ;
case ZEND_ACC_PROTECTED : {
2014-06-18 06:47:01 +08:00
property_info - > name = zend_mangle_property_name ( " * " , 1 , name - > val , name - > len , ce - > type & ZEND_INTERNAL_CLASS ) ;
2003-07-08 00:22:56 +08:00
}
break ;
case ZEND_ACC_PUBLIC :
2014-08-26 01:24:55 +08:00
property_info - > name = zend_string_copy ( name ) ;
2003-07-08 00:22:56 +08:00
break ;
2003-07-07 03:55:20 +08:00
}
2010-04-20 19:05:54 +08:00
2014-06-18 06:47:01 +08:00
property_info - > name = zend_new_interned_string ( property_info - > name TSRMLS_CC ) ;
property_info - > flags = access_type ;
property_info - > doc_comment = doc_comment ;
property_info - > ce = ce ;
zend_hash_update_ptr ( & ce - > properties_info , name , property_info ) ;
2003-07-08 00:22:56 +08:00
return SUCCESS ;
2003-07-07 03:55:20 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property ( zend_class_entry * ce , const char * name , int name_length , zval * property , int access_type TSRMLS_DC ) /* { { { */
2007-11-03 03:40:39 +08:00
{
2014-08-26 01:24:55 +08:00
zend_string * key = zend_string_init ( name , name_length , ce - > type & ZEND_INTERNAL_CLASS ) ;
2014-02-10 14:04:30 +08:00
int ret = zend_declare_property_ex ( ce , key , property , access_type , NULL TSRMLS_CC ) ;
2014-08-26 01:24:55 +08:00
zend_string_release ( key ) ;
2014-02-10 14:04:30 +08:00
return ret ;
2007-11-03 03:40:39 +08:00
}
/* }}} */
2003-08-24 03:37:39 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property_null ( zend_class_entry * ce , const char * name , int name_length , int access_type TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
2014-02-10 14:04:30 +08:00
zval property ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( & property ) ;
return zend_declare_property ( ce , name , name_length , & property , access_type TSRMLS_CC ) ;
2003-08-24 03:37:39 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int zend_declare_property_bool ( zend_class_entry * ce , const char * name , int name_length , zend_long value , int access_type TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
2014-02-10 14:04:30 +08:00
zval property ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( & property , value ) ;
return zend_declare_property ( ce , name , name_length , & property , access_type TSRMLS_CC ) ;
2005-02-05 04:24:21 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int zend_declare_property_long ( zend_class_entry * ce , const char * name , int name_length , zend_long value , int access_type TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
2014-02-10 14:04:30 +08:00
zval property ;
2006-05-10 07:53:23 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & property , value ) ;
2014-02-10 14:04:30 +08:00
return zend_declare_property ( ce , name , name_length , & property , access_type TSRMLS_CC ) ;
2003-08-25 01:32:47 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-25 01:32:47 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property_double ( zend_class_entry * ce , const char * name , int name_length , double value , int access_type TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
2014-02-10 14:04:30 +08:00
zval property ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_DOUBLE ( & property , value ) ;
return zend_declare_property ( ce , name , name_length , & property , access_type TSRMLS_CC ) ;
2005-02-05 04:24:21 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property_string ( zend_class_entry * ce , const char * name , int name_length , const char * value , int access_type TSRMLS_DC ) /* { { { */
2003-08-25 01:32:47 +08:00
{
2014-02-10 14:04:30 +08:00
zval property ;
2006-05-10 07:53:23 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_NEW_STR ( & property , zend_string_init ( value , strlen ( value ) , ce - > type & ZEND_INTERNAL_CLASS ) ) ;
2014-02-10 14:04:30 +08:00
return zend_declare_property ( ce , name , name_length , & property , access_type TSRMLS_CC ) ;
2003-08-24 03:37:39 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2014-08-29 01:17:47 +08:00
ZEND_API int zend_declare_property_stringl ( zend_class_entry * ce , const char * name , int name_length , const char * value , size_t value_len , int access_type TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
2014-02-10 14:04:30 +08:00
zval property ;
2006-05-10 07:53:23 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_NEW_STR ( & property , zend_string_init ( value , value_len , ce - > type & ZEND_INTERNAL_CLASS ) ) ;
2014-02-10 14:04:30 +08:00
return zend_declare_property ( ce , name , name_length , & property , access_type TSRMLS_CC ) ;
2005-02-05 04:24:21 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant ( zend_class_entry * ce , const char * name , size_t name_length , zval * value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-06-17 03:32:58 +08:00
if ( Z_CONSTANT_P ( value ) ) {
ce - > ce_flags & = ~ ZEND_ACC_CONSTANTS_UPDATED ;
}
2014-02-10 14:04:30 +08:00
return zend_hash_str_update ( & ce - > constants_table , name , name_length , value ) ?
SUCCESS : FAILURE ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant_null ( zend_class_entry * ce , const char * name , size_t name_length TSRMLS_DC ) /* { { { */
2006-03-06 00:12:24 +08:00
{
2014-02-10 14:04:30 +08:00
zval constant ;
2006-03-06 00:12:24 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( & constant ) ;
return zend_declare_class_constant ( ce , name , name_length , & constant TSRMLS_CC ) ;
2006-03-06 00:12:24 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2006-03-06 00:12:24 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int zend_declare_class_constant_long ( zend_class_entry * ce , const char * name , size_t name_length , zend_long value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval constant ;
2005-09-01 18:05:32 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & constant , value ) ;
2014-02-10 14:04:30 +08:00
return zend_declare_class_constant ( ce , name , name_length , & constant TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant_bool ( zend_class_entry * ce , const char * name , size_t name_length , zend_bool value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval constant ;
2005-09-01 18:05:32 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( & constant , value ) ;
return zend_declare_class_constant ( ce , name , name_length , & constant TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant_double ( zend_class_entry * ce , const char * name , size_t name_length , double value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval constant ;
2005-09-01 18:05:32 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_DOUBLE ( & constant , value ) ;
return zend_declare_class_constant ( ce , name , name_length , & constant TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant_stringl ( zend_class_entry * ce , const char * name , size_t name_length , const char * value , size_t value_length TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval constant ;
2005-09-01 18:05:32 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_NEW_STR ( & constant , zend_string_init ( value , value_length , ce - > type & ZEND_INTERNAL_CLASS ) ) ;
2014-02-10 14:04:30 +08:00
return zend_declare_class_constant ( ce , name , name_length , & constant TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant_string ( zend_class_entry * ce , const char * name , size_t name_length , const char * value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
return zend_declare_class_constant_stringl ( ce , name , name_length , value , strlen ( value ) TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API void zend_update_property ( zend_class_entry * scope , zval * object , const char * name , int name_length , zval * value TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
2014-02-10 14:04:30 +08:00
zval property ;
2003-08-24 03:37:39 +08:00
zend_class_entry * old_scope = EG ( scope ) ;
2006-05-10 07:53:23 +08:00
2003-08-24 03:37:39 +08:00
EG ( scope ) = scope ;
if ( ! Z_OBJ_HT_P ( object ) - > write_property ) {
2014-03-28 06:11:22 +08:00
zend_string * class_name = zend_get_object_classname ( Z_OBJ_P ( object ) TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
zend_error ( E_CORE_ERROR , " Property %s of class %s cannot be updated " , name , class_name - > val ) ;
2003-08-24 03:37:39 +08:00
}
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( & property , name , name_length ) ;
2014-07-08 00:54:31 +08:00
Z_OBJ_HT_P ( object ) - > write_property ( object , & property , value , NULL TSRMLS_CC ) ;
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & property ) ;
2003-08-24 03:37:39 +08:00
EG ( scope ) = old_scope ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API void zend_update_property_null ( zend_class_entry * scope , zval * object , const char * name , int name_length TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2003-08-24 03:37:39 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( & tmp ) ;
zend_update_property ( scope , object , name , name_length , & tmp TSRMLS_CC ) ;
2003-08-24 03:37:39 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API void zend_update_property_bool ( zend_class_entry * scope , zval * object , const char * name , int name_length , zend_long value TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( & tmp , value ) ;
zend_update_property ( scope , object , name , name_length , & tmp TSRMLS_CC ) ;
2005-02-05 04:24:21 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API void zend_update_property_long ( zend_class_entry * scope , zval * object , const char * name , int name_length , zend_long value TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & tmp , value ) ;
2014-02-10 14:04:30 +08:00
zend_update_property ( scope , object , name , name_length , & tmp TSRMLS_CC ) ;
2003-08-24 03:37:39 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API void zend_update_property_double ( zend_class_entry * scope , zval * object , const char * name , int name_length , double value TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_DOUBLE ( & tmp , value ) ;
zend_update_property ( scope , object , name , name_length , & tmp TSRMLS_CC ) ;
2005-02-05 04:24:21 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2014-02-21 20:14:42 +08:00
ZEND_API void zend_update_property_str ( zend_class_entry * scope , zval * object , const char * name , int name_length , zend_string * value TSRMLS_DC ) /* { { { */
{
zval tmp ;
2014-02-28 17:29:18 +08:00
ZVAL_STR ( & tmp , value ) ;
2014-02-21 20:14:42 +08:00
zend_update_property ( scope , object , name , name_length , & tmp TSRMLS_CC ) ;
}
/* }}} */
2011-09-13 21:29:35 +08:00
ZEND_API void zend_update_property_string ( zend_class_entry * scope , zval * object , const char * name , int name_length , const char * value TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & tmp , value ) ;
Z_SET_REFCOUNT ( tmp , 0 ) ;
zend_update_property ( scope , object , name , name_length , & tmp TSRMLS_CC ) ;
2003-08-24 03:37:39 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2014-08-29 01:17:47 +08:00
ZEND_API void zend_update_property_stringl ( zend_class_entry * scope , zval * object , const char * name , int name_length , const char * value , size_t value_len TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( & tmp , value , value_len ) ;
Z_SET_REFCOUNT ( tmp , 0 ) ;
zend_update_property ( scope , object , name , name_length , & tmp TSRMLS_CC ) ;
2005-02-05 04:24:21 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_update_static_property ( zend_class_entry * scope , const char * name , int name_length , zval * value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval * property ;
2005-09-01 18:05:32 +08:00
zend_class_entry * old_scope = EG ( scope ) ;
2014-08-26 01:24:55 +08:00
zend_string * key = zend_string_init ( name , name_length , 0 ) ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
EG ( scope ) = scope ;
2014-07-08 00:54:31 +08:00
property = zend_std_get_static_property ( scope , key , 0 , NULL TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
EG ( scope ) = old_scope ;
2014-08-26 01:24:55 +08:00
zend_string_free ( key ) ;
2005-09-01 18:05:32 +08:00
if ( ! property ) {
return FAILURE ;
} else {
2014-02-10 14:04:30 +08:00
if ( property ! = value ) {
if ( Z_ISREF_P ( property ) ) {
zval_dtor ( property ) ;
ZVAL_COPY_VALUE ( property , value ) ;
2007-10-07 13:22:07 +08:00
if ( Z_REFCOUNT_P ( value ) > 0 ) {
2014-04-04 06:52:53 +08:00
zval_opt_copy_ctor ( property ) ;
2005-09-01 18:05:32 +08:00
}
} else {
2014-02-10 14:04:30 +08:00
zval garbage ;
2005-09-01 18:05:32 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( & garbage , property ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( value ) ;
2014-02-10 14:04:30 +08:00
if ( Z_ISREF_P ( value ) ) {
SEPARATE_ZVAL ( value ) ;
2005-09-01 18:05:32 +08:00
}
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( property , value ) ;
2005-09-01 18:05:32 +08:00
zval_ptr_dtor ( & garbage ) ;
}
}
return SUCCESS ;
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_update_static_property_null ( zend_class_entry * scope , const char * name , int name_length TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
ZVAL_NULL ( & tmp ) ;
return zend_update_static_property ( scope , name , name_length , & tmp TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int zend_update_static_property_bool ( zend_class_entry * scope , const char * name , int name_length , zend_long value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( & tmp , value ) ;
return zend_update_static_property ( scope , name , name_length , & tmp TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2014-08-26 01:24:55 +08:00
ZEND_API int zend_update_static_property_long ( zend_class_entry * scope , const char * name , int name_length , zend_long value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & tmp , value ) ;
2014-02-10 14:04:30 +08:00
return zend_update_static_property ( scope , name , name_length , & tmp TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_update_static_property_double ( zend_class_entry * scope , const char * name , int name_length , double value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_DOUBLE ( & tmp , value ) ;
return zend_update_static_property ( scope , name , name_length , & tmp TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_update_static_property_string ( zend_class_entry * scope , const char * name , int name_length , const char * value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & tmp , value ) ;
Z_SET_REFCOUNT ( tmp , 0 ) ;
return zend_update_static_property ( scope , name , name_length , & tmp TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2014-08-29 01:17:47 +08:00
ZEND_API int zend_update_static_property_stringl ( zend_class_entry * scope , const char * name , int name_length , const char * value , size_t value_len TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval tmp ;
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( & tmp , value , value_len ) ;
Z_SET_REFCOUNT ( tmp , 0 ) ;
return zend_update_static_property ( scope , name , name_length , & tmp TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API zval * zend_read_property ( zend_class_entry * scope , zval * object , const char * name , int name_length , zend_bool silent TSRMLS_DC ) /* { { { */
2003-08-24 08:36:53 +08:00
{
2014-02-10 14:04:30 +08:00
zval property , * value ;
2003-08-24 08:36:53 +08:00
zend_class_entry * old_scope = EG ( scope ) ;
2014-02-27 19:40:13 +08:00
zval rv ;
2006-05-10 07:53:23 +08:00
2003-08-24 08:36:53 +08:00
EG ( scope ) = scope ;
if ( ! Z_OBJ_HT_P ( object ) - > read_property ) {
2014-03-28 06:11:22 +08:00
zend_string * class_name = zend_get_object_classname ( Z_OBJ_P ( object ) TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
zend_error ( E_CORE_ERROR , " Property %s of class %s cannot be read " , name , class_name - > val ) ;
2003-08-24 08:36:53 +08:00
}
2006-05-10 07:53:23 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( & property , name , name_length ) ;
2014-07-08 00:54:31 +08:00
value = Z_OBJ_HT_P ( object ) - > read_property ( object , & property , silent ? BP_VAR_IS : BP_VAR_R , NULL , & rv TSRMLS_CC ) ;
2005-11-24 02:51:44 +08:00
zval_ptr_dtor ( & property ) ;
2006-05-10 07:53:23 +08:00
2003-08-24 08:36:53 +08:00
EG ( scope ) = old_scope ;
return value ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 08:36:53 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API zval * zend_read_static_property ( zend_class_entry * scope , const char * name , int name_length , zend_bool silent TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
2014-02-10 14:04:30 +08:00
zval * property ;
2005-09-01 18:05:32 +08:00
zend_class_entry * old_scope = EG ( scope ) ;
2014-08-26 01:24:55 +08:00
zend_string * key = zend_string_init ( name , name_length , 0 ) ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
EG ( scope ) = scope ;
2014-07-08 00:54:31 +08:00
property = zend_std_get_static_property ( scope , key , silent , NULL TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
EG ( scope ) = old_scope ;
2014-08-26 01:24:55 +08:00
zend_string_free ( key ) ;
2005-09-01 18:05:32 +08:00
2014-02-10 14:04:30 +08:00
return property ;
2005-09-01 18:05:32 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-09 01:47:31 +08:00
ZEND_API void zend_save_error_handling ( zend_error_handling * current TSRMLS_DC ) /* { { { */
{
current - > handling = EG ( error_handling ) ;
current - > exception = EG ( exception_class ) ;
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( & current - > user_handler , & EG ( user_error_handler ) ) ;
2008-08-09 01:47:31 +08:00
}
/* }}} */
ZEND_API void zend_replace_error_handling ( zend_error_handling_t error_handling , zend_class_entry * exception_class , zend_error_handling * current TSRMLS_DC ) /* { { { */
{
if ( current ) {
zend_save_error_handling ( current TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
if ( error_handling ! = EH_NORMAL & & Z_TYPE ( EG ( user_error_handler ) ) ! = IS_UNDEF ) {
2008-08-12 01:19:20 +08:00
zval_ptr_dtor ( & EG ( user_error_handler ) ) ;
2014-02-10 14:04:30 +08:00
ZVAL_UNDEF ( & EG ( user_error_handler ) ) ;
2008-08-12 01:19:20 +08:00
}
2008-08-09 01:47:31 +08:00
}
EG ( error_handling ) = error_handling ;
EG ( exception_class ) = error_handling = = EH_THROW ? exception_class : NULL ;
}
/* }}} */
2014-03-20 02:43:36 +08:00
static int same_zval ( zval * zv1 , zval * zv2 ) /* { { { */
{
if ( Z_TYPE_P ( zv1 ) ! = Z_TYPE_P ( zv2 ) ) {
return 0 ;
}
switch ( Z_TYPE_P ( zv1 ) ) {
case IS_UNDEF :
case IS_NULL :
2014-04-30 22:32:42 +08:00
case IS_FALSE :
case IS_TRUE :
2014-03-20 02:43:36 +08:00
return 1 ;
2014-08-26 01:24:55 +08:00
case IS_LONG :
return Z_LVAL_P ( zv1 ) = = Z_LVAL_P ( zv2 ) ;
2014-03-20 02:43:36 +08:00
case IS_DOUBLE :
2014-08-26 01:24:55 +08:00
return Z_LVAL_P ( zv1 ) = = Z_LVAL_P ( zv2 ) ;
2014-03-20 02:43:36 +08:00
case IS_STRING :
case IS_ARRAY :
case IS_OBJECT :
case IS_RESOURCE :
return Z_COUNTED_P ( zv1 ) = = Z_COUNTED_P ( zv2 ) ;
default :
return 0 ;
}
}
/* }}} */
2008-08-12 01:19:20 +08:00
ZEND_API void zend_restore_error_handling ( zend_error_handling * saved TSRMLS_DC ) /* { { { */
2008-08-09 01:47:31 +08:00
{
EG ( error_handling ) = saved - > handling ;
EG ( exception_class ) = saved - > handling = = EH_THROW ? saved - > exception : NULL ;
2014-02-12 22:08:11 +08:00
if ( Z_TYPE ( saved - > user_handler ) ! = IS_UNDEF
2014-03-20 02:43:36 +08:00
& & ! same_zval ( & saved - > user_handler , & EG ( user_error_handler ) ) ) {
2014-02-10 14:04:30 +08:00
zval_ptr_dtor ( & EG ( user_error_handler ) ) ;
ZVAL_COPY_VALUE ( & EG ( user_error_handler ) , & saved - > user_handler ) ;
2014-02-12 22:08:11 +08:00
} else if ( Z_TYPE ( saved - > user_handler ) ) {
zval_ptr_dtor ( & saved - > user_handler ) ;
2008-08-12 01:19:20 +08:00
}
2014-02-10 14:04:30 +08:00
ZVAL_UNDEF ( & saved - > user_handler ) ;
2008-08-09 01:47:31 +08:00
}
/* }}} */
2014-02-10 14:04:30 +08:00
ZEND_API zend_string * zend_find_alias_name ( zend_class_entry * ce , zend_string * name ) /* { { { */
2013-03-21 21:09:30 +08:00
{
zend_trait_alias * alias , * * alias_ptr ;
2013-08-29 14:02:15 +08:00
if ( ( alias_ptr = ce - > trait_aliases ) ) {
2013-03-21 21:09:30 +08:00
alias = * alias_ptr ;
2013-08-29 11:33:42 +08:00
while ( alias ) {
2014-02-10 14:04:30 +08:00
if ( alias - > alias - > len = = name - > len & &
! strncasecmp ( name - > val , alias - > alias - > val , alias - > alias - > len ) ) {
2013-08-29 11:33:42 +08:00
return alias - > alias ;
}
alias_ptr + + ;
alias = * alias_ptr ;
}
2013-03-21 21:09:30 +08:00
}
return name ;
}
/* }}} */
2014-02-10 14:04:30 +08:00
ZEND_API zend_string * zend_resolve_method_name ( zend_class_entry * ce , zend_function * f ) /* { { { */
2013-03-21 21:09:30 +08:00
{
zend_function * func ;
HashTable * function_table ;
2014-04-18 23:18:11 +08:00
zend_string * name ;
2013-03-21 21:09:30 +08:00
if ( f - > common . type ! = ZEND_USER_FUNCTION | |
* ( f - > op_array . refcount ) < 2 | |
! f - > common . scope | |
! f - > common . scope - > trait_aliases ) {
return f - > common . function_name ;
}
function_table = & ce - > function_table ;
2014-04-22 21:46:34 +08:00
ZEND_HASH_FOREACH_STR_KEY_PTR ( function_table , name , func ) {
2013-03-21 21:09:30 +08:00
if ( func = = f ) {
2014-04-18 23:18:11 +08:00
if ( ! name ) {
2013-03-21 21:09:30 +08:00
return f - > common . function_name ;
}
2014-02-10 14:04:30 +08:00
if ( name - > len = = f - > common . function_name - > len & &
! strncasecmp ( name - > val , f - > common . function_name - > val , f - > common . function_name - > len ) ) {
2013-03-21 21:09:30 +08:00
return f - > common . function_name ;
}
2014-02-10 14:04:30 +08:00
return zend_find_alias_name ( f - > common . scope , name ) ;
2013-03-21 21:09:30 +08:00
}
2014-04-18 23:18:11 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2013-03-21 21:09:30 +08:00
return f - > common . function_name ;
}
/* }}} */
2003-02-01 09:49:15 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* indent - tabs - mode : t
* End :
*/