PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - Zend - zend_API.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 1573 2093 75.2 %
Date: 2015-05-21 Functions: 130 179 72.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2015 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    |          Andrei Zmievski <andrei@php.net>                            |
      18             :    +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #include "zend.h"
      24             : #include "zend_execute.h"
      25             : #include "zend_API.h"
      26             : #include "zend_modules.h"
      27             : #include "zend_constants.h"
      28             : #include "zend_exceptions.h"
      29             : #include "zend_closures.h"
      30             : #include "zend_inheritance.h"
      31             : 
      32             : #ifdef HAVE_STDARG_H
      33             : #include <stdarg.h>
      34             : #endif
      35             : 
      36             : /* these variables are true statics/globals, and have to be mutex'ed on every access */
      37             : ZEND_API HashTable module_registry;
      38             : 
      39             : static zend_module_entry **module_request_startup_handlers;
      40             : static zend_module_entry **module_request_shutdown_handlers;
      41             : static zend_module_entry **module_post_deactivate_handlers;
      42             : 
      43             : static zend_class_entry  **class_cleanup_handlers;
      44             : 
      45             : /* this function doesn't check for too many parameters */
      46           0 : ZEND_API int zend_get_parameters(int ht, int param_count, ...) /* {{{ */
      47             : {
      48             :         int arg_count;
      49             :         va_list ptr;
      50             :         zval **param, *param_ptr;
      51             : 
      52           0 :         param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
      53           0 :         arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
      54             : 
      55           0 :         if (param_count>arg_count) {
      56           0 :                 return FAILURE;
      57             :         }
      58             : 
      59           0 :         va_start(ptr, param_count);
      60             : 
      61           0 :         while (param_count-->0) {
      62           0 :                 param = va_arg(ptr, zval **);
      63           0 :                 if (!Z_ISREF_P(param_ptr) && Z_REFCOUNT_P(param_ptr) > 1) {
      64             :                         zval new_tmp;
      65             : 
      66           0 :                         ZVAL_DUP(&new_tmp, param_ptr);
      67             :                         Z_DELREF_P(param_ptr);
      68           0 :                         ZVAL_COPY_VALUE(param_ptr, &new_tmp);
      69             :                 }
      70           0 :                 *param = param_ptr;
      71           0 :                 param_ptr++;
      72             :         }
      73           0 :         va_end(ptr);
      74             : 
      75           0 :         return SUCCESS;
      76             : }
      77             : /* }}} */
      78             : 
      79             : /* Zend-optimized Extended functions */
      80             : /* this function doesn't check for too many parameters */
      81           0 : ZEND_API int zend_get_parameters_ex(int param_count, ...) /* {{{ */
      82             : {
      83             :         int arg_count;
      84             :         va_list ptr;
      85             :         zval **param, *param_ptr;
      86             : 
      87           0 :         param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
      88           0 :         arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
      89             : 
      90           0 :         if (param_count>arg_count) {
      91           0 :                 return FAILURE;
      92             :         }
      93             : 
      94           0 :         va_start(ptr, param_count);
      95           0 :         while (param_count-->0) {
      96           0 :                 param = va_arg(ptr, zval **);
      97           0 :                 *param = param_ptr;
      98           0 :                 param_ptr++;
      99             :         }
     100           0 :         va_end(ptr);
     101             : 
     102           0 :         return SUCCESS;
     103             : }
     104             : /* }}} */
     105             : 
     106       21426 : ZEND_API int _zend_get_parameters_array_ex(int param_count, zval *argument_array) /* {{{ */
     107             : {
     108             :         zval *param_ptr;
     109             :         int arg_count;
     110             : 
     111       21426 :         param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
     112       21426 :         arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
     113             : 
     114       21426 :         if (param_count>arg_count) {
     115           0 :                 return FAILURE;
     116             :         }
     117             : 
     118      260451 :         while (param_count-->0) {
     119      217599 :                 ZVAL_COPY_VALUE(argument_array, param_ptr);
     120      217599 :                 argument_array++;
     121      217599 :                 param_ptr++;
     122             :         }
     123             : 
     124       21426 :         return SUCCESS;
     125             : }
     126             : /* }}} */
     127             : 
     128           0 : ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array) /* {{{ */
     129             : {
     130             :         zval *param_ptr;
     131             :         int arg_count;
     132             : 
     133           0 :         param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
     134           0 :         arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
     135             : 
     136           0 :         if (param_count>arg_count) {
     137           0 :                 return FAILURE;
     138             :         }
     139             : 
     140           0 :         while (param_count-->0) {
     141           0 :                 if (Z_REFCOUNTED_P(param_ptr)) {
     142             :                         Z_ADDREF_P(param_ptr);
     143             :                 }
     144           0 :                 zend_hash_next_index_insert_new(Z_ARRVAL_P(argument_array), param_ptr);
     145           0 :                 param_ptr++;
     146             :         }
     147             : 
     148           0 :         return SUCCESS;
     149             : }
     150             : /* }}} */
     151             : 
     152          30 : ZEND_API void zend_wrong_param_count(void) /* {{{ */
     153             : {
     154             :         const char *space;
     155          30 :         const char *class_name = get_active_class_name(&space);
     156             : 
     157          30 :         zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name());
     158          30 : }
     159             : /* }}} */
     160             : 
     161             : /* Argument parsing API -- andrei */
     162        8099 : ZEND_API char *zend_get_type_by_const(int type) /* {{{ */
     163             : {
     164        8099 :         switch(type) {
     165             :                 case IS_FALSE:
     166             :                 case IS_TRUE:
     167             :                 case _IS_BOOL:
     168         680 :                         return "boolean";
     169             :                 case IS_LONG:
     170         749 :                         return "integer";
     171             :                 case IS_DOUBLE:
     172         691 :                         return "float";
     173             :                 case IS_STRING:
     174        2128 :                         return "string";
     175             :                 case IS_OBJECT:
     176         758 :                         return "object";
     177             :                 case IS_RESOURCE:
     178         436 :                         return "resource";
     179             :                 case IS_NULL:
     180         633 :                         return "null";
     181             :                 case IS_CALLABLE:
     182           0 :                         return "callable";
     183             :                 case IS_ARRAY:
     184        2024 :                         return "array";
     185             :                 default:
     186           0 :                         return "unknown";
     187             :         }
     188             : }
     189             : /* }}} */
     190             : 
     191        7827 : ZEND_API char *zend_zval_type_name(const zval *arg) /* {{{ */
     192             : {
     193        7827 :         ZVAL_DEREF(arg);
     194        7827 :         return zend_get_type_by_const(Z_TYPE_P(arg));
     195             : }
     196             : /* }}} */
     197             : 
     198             : #ifdef FAST_ZPP
     199         375 : ZEND_API void ZEND_FASTCALL zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args) /* {{{ */
     200             : {
     201         375 :         zend_function *active_function = EG(current_execute_data)->func;
     202         375 :         const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
     203             : 
     204        1125 :         zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects %s %d parameter%s, %d given",
     205             :                 class_name, \
     206         375 :                 class_name[0] ? "::" : "", \
     207         375 :                 active_function->common.function_name->val,
     208             :                 min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
     209             :                 num_args < min_num_args ? min_num_args : max_num_args,
     210             :                 (num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
     211             :                 num_args);
     212         375 : }
     213             : /* }}} */
     214             : 
     215        1032 : ZEND_API void ZEND_FASTCALL zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg) /* {{{ */
     216             : {
     217             :         const char *space;
     218        1032 :         const char *class_name = get_active_class_name(&space);
     219             :         static const char * const expected_error[] = {
     220             :                 Z_EXPECTED_TYPES(Z_EXPECTED_TYPE_STR)
     221             :                 NULL
     222             :         };
     223             : 
     224        1032 :         zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
     225             :                 class_name, space, get_active_function_name(), num, expected_error[expected_type], zend_zval_type_name(arg));
     226        1032 : }
     227             : /* }}} */
     228             : 
     229           0 : ZEND_API void ZEND_FASTCALL zend_wrong_paramer_class_error(int num, char *name, zval *arg) /* {{{ */
     230             : {
     231             :         const char *space;
     232           0 :         const char *class_name = get_active_class_name(&space);
     233             : 
     234           0 :         zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
     235             :                 class_name, space, get_active_function_name(), num, name, zend_zval_type_name(arg));
     236           0 : }
     237             : /* }}} */
     238             : 
     239         101 : ZEND_API void ZEND_FASTCALL zend_wrong_callback_error(int severity, int num, char *error) /* {{{ */
     240             : {
     241             :         const char *space;
     242         101 :         const char *class_name = get_active_class_name(&space);
     243             : 
     244         101 :         if (severity == E_WARNING) {
     245          98 :                 zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid callback, %s",
     246             :                         class_name, space, get_active_function_name(), num, error);
     247             :         } else {
     248           3 :                 zend_error(severity, "%s%s%s() expects parameter %d to be a valid callback, %s",
     249             :                         class_name, space, get_active_function_name(), num, error);
     250             :         }
     251         101 :         efree(error);
     252         101 : }
     253             : /* }}} */
     254             : 
     255           4 : ZEND_API int ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null) /* {{{ */
     256             : {
     257           4 :         zend_class_entry *ce_base = *pce;
     258             : 
     259           4 :         if (check_null && Z_TYPE_P(arg) == IS_NULL) {
     260           0 :                 *pce = NULL;
     261           0 :                 return 1;
     262             :         }
     263           4 :         convert_to_string_ex(arg);
     264           4 :         *pce = zend_lookup_class(Z_STR_P(arg));
     265           4 :         if (ce_base) {
     266           4 :                 if ((!*pce || !instanceof_function(*pce, ce_base))) {
     267             :                         const char *space;
     268           2 :                         const char *class_name = get_active_class_name(&space);
     269             : 
     270           4 :                         zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a class name derived from %s, '%s' given",
     271             :                                 class_name, space, get_active_function_name(), num,
     272           4 :                                 ce_base->name->val, Z_STRVAL_P(arg));
     273           2 :                         *pce = NULL;
     274           2 :                         return 0;
     275             :                 }
     276             :         }
     277           2 :         if (!*pce) {
     278             :                 const char *space;
     279           0 :                 const char *class_name = get_active_class_name(&space);
     280             : 
     281           0 :                 zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid class name, '%s' given",
     282             :                         class_name, space, get_active_function_name(), num,
     283           0 :                         Z_STRVAL_P(arg));
     284           0 :                 return 0;
     285             :         }
     286           2 :         return 1;
     287             : }
     288             : /* }}} */
     289             : #endif
     290             : 
     291        1242 : ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, zend_bool *dest) /* {{{ */
     292             : {
     293        1242 :         if (EXPECTED(Z_TYPE_P(arg) <= IS_STRING)) {
     294        1081 :                 *dest = zend_is_true(arg);
     295             :         } else {
     296         161 :                 return 0;
     297             :         }
     298        1081 :         return 1;
     299             : }
     300             : /* }}} */
     301             : 
     302        1215 : ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_slow(zval *arg, zend_bool *dest) /* {{{ */
     303             : {
     304        1215 :         if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
     305           0 :                 return 0;
     306             :         }
     307        1215 :         return zend_parse_arg_bool_weak(arg, dest);
     308             : }
     309             : /* }}} */
     310             : 
     311       11556 : ZEND_API int ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest) /* {{{ */
     312             : {
     313             :         if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
     314        2982 :                 if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) {
     315           3 :                         return 0;
     316             :                 }
     317        2979 :                 if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) {
     318           9 :                         return 0;
     319             :                 } else {
     320        5940 :                         *dest = zend_dval_to_lval(Z_DVAL_P(arg));
     321             :                 }
     322        8574 :         } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
     323             :                 double d;
     324             :                 int type;
     325             : 
     326        1686 :                 if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) {
     327        1380 :                         if (EXPECTED(type != 0)) {
     328         224 :                                 if (UNEXPECTED(zend_isnan(d))) {
     329           0 :                                         return 0;
     330             :                                 }
     331         224 :                                 if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) {
     332           0 :                                         return 0;
     333             :                                 } else {
     334         448 :                                         *dest = zend_dval_to_lval(d);
     335             :                                 }
     336             :                         } else {
     337        1156 :                                 return 0;
     338             :                         }
     339             :                 }
     340        6888 :         } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
     341        5412 :                 *dest = 0;
     342        1476 :         } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
     343         600 :                 *dest = 1;
     344             :         } else {
     345         876 :                 return 0;
     346             :         }
     347        9512 :         return 1;
     348             : }
     349             : /* }}} */
     350             : 
     351       11524 : ZEND_API int ZEND_FASTCALL zend_parse_arg_long_slow(zval *arg, zend_long *dest) /* {{{ */
     352             : {
     353       11524 :         if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
     354           0 :                 return 0;
     355             :         }
     356       11524 :         return zend_parse_arg_long_weak(arg, dest);
     357             : }
     358             : /* }}} */
     359             : 
     360           0 : ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_weak(zval *arg, zend_long *dest) /* {{{ */
     361             : {
     362           0 :         if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
     363           0 :                 if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) {
     364           0 :                         return 0;
     365             :                 }
     366           0 :                 if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) {
     367           0 :                         *dest = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
     368             :                 } else {
     369           0 :                         *dest = zend_dval_to_lval(Z_DVAL_P(arg));
     370             :                 }
     371           0 :         } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
     372             :                 double d;
     373             :                 int type;
     374             : 
     375           0 :                 if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) {
     376           0 :                         if (EXPECTED(type != 0)) {
     377           0 :                                 if (UNEXPECTED(zend_isnan(d))) {
     378           0 :                                         return 0;
     379             :                                 }
     380           0 :                                 if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) {
     381           0 :                                         *dest = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
     382             :                                 } else {
     383           0 :                                         *dest = zend_dval_to_lval(d);
     384             :                                 }
     385             :                         } else {
     386           0 :                                 return 0;
     387             :                         }
     388             :                 }
     389           0 :         } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
     390           0 :                 *dest = 0;
     391           0 :         } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
     392           0 :                 *dest = 1;
     393             :         } else {
     394           0 :                 return 0;
     395             :         }
     396           0 :         return 1;
     397             : }
     398             : /* }}} */
     399             : 
     400           0 : ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_slow(zval *arg, zend_long *dest) /* {{{ */
     401             : {
     402           0 :         if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
     403           0 :                 return 0;
     404             :         }
     405           0 :         return zend_parse_arg_long_cap_weak(arg, dest);
     406             : }
     407             : /* }}} */
     408             : 
     409        6458 : ZEND_API int ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest) /* {{{ */
     410             : {
     411        6458 :         if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
     412        4936 :                 *dest = (double)Z_LVAL_P(arg);
     413        1522 :         } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
     414             :                 zend_long l;
     415             :                 int type;
     416             : 
     417         656 :                 if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, dest)) != IS_DOUBLE)) {
     418         436 :                         if (EXPECTED(type != 0)) {
     419         183 :                                 *dest = (double)(l);
     420             :                         } else {
     421         253 :                                 return 0;
     422             :                         }
     423             :                 }
     424         866 :         } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
     425         467 :                 *dest = 0.0;
     426         399 :         } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
     427         193 :                 *dest = 1.0;
     428             :         } else {
     429         206 :                 return 0;
     430             :         }
     431        5999 :         return 1;
     432             : }
     433             : /* }}} */
     434             : 
     435        6430 : ZEND_API int ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest) /* {{{ */
     436             : {
     437        6430 :         if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
     438             :                 /* SSTH Exception: IS_LONG may be accepted instead as IS_DOUBLE */
     439        4928 :                 *dest = (double)Z_LVAL_P(arg);
     440        1502 :         } else if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
     441           0 :                 return 0;
     442             :         }
     443        6430 :         return zend_parse_arg_double_weak(arg, dest);
     444             : }
     445             : /* }}} */
     446             : 
     447      257030 : ZEND_API int ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest) /* {{{ */
     448             : {
     449      257030 :         if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) {
     450       55387 :                 convert_to_string(arg);
     451       55387 :                 *dest = Z_STR_P(arg);
     452      201643 :         } else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
     453      200497 :                 if (Z_OBJ_HANDLER_P(arg, cast_object)) {
     454             :                         zval obj;
     455      200497 :                         if (Z_OBJ_HANDLER_P(arg, cast_object)(arg, &obj, IS_STRING) == SUCCESS) {
     456      200308 :                                 zval_ptr_dtor(arg);
     457      200308 :                                 ZVAL_COPY_VALUE(arg, &obj);
     458      200308 :                                 *dest = Z_STR_P(arg);
     459      200308 :                                 return 1;
     460             :                         }
     461             :                 }
     462             :                 /* Standard PHP objects */
     463         189 :                 if (Z_OBJ_HT_P(arg) == &std_object_handlers || !Z_OBJ_HANDLER_P(arg, cast_object)) {
     464         186 :                         SEPARATE_ZVAL_NOREF(arg);
     465         186 :                         if (zend_std_cast_object_tostring(arg, arg, IS_STRING) == SUCCESS) {
     466           0 :                                 *dest = Z_STR_P(arg);
     467           0 :                                 return 1;
     468             :                         }
     469             :                 }
     470         189 :                 if (!Z_OBJ_HANDLER_P(arg, cast_object) && Z_OBJ_HANDLER_P(arg, get)) {
     471             :                         zval rv;
     472           0 :                         zval *z = Z_OBJ_HANDLER_P(arg, get)(arg, &rv);
     473             : 
     474             :                         Z_ADDREF_P(z);
     475           0 :                         if (Z_TYPE_P(z) != IS_OBJECT) {
     476             :                                 zval_dtor(arg);
     477           0 :                                 ZVAL_NULL(arg);
     478           0 :                                 if (!zend_make_printable_zval(z, arg)) {
     479           0 :                                         ZVAL_ZVAL(arg, z, 1, 1);
     480             :                                 }
     481           0 :                                 *dest = Z_STR_P(arg);
     482           0 :                                 return 1;
     483             :                         }
     484           0 :                         zval_ptr_dtor(z);
     485             :                 }
     486         189 :                 return 0;
     487             :         } else {
     488        1146 :                 return 0;
     489             :         }
     490       55387 :         return 1;
     491             : }
     492             : /* }}} */
     493             : 
     494      256533 : ZEND_API int ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest) /* {{{ */
     495             : {
     496      256533 :         if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
     497           1 :                 return 0;
     498             :         }
     499      256532 :         return zend_parse_arg_str_weak(arg, dest);
     500             : }
     501             : /* }}} */
     502             : 
     503    20018898 : static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, const char **spec, char **error, int *severity) /* {{{ */
     504             : {
     505    20018898 :         const char *spec_walk = *spec;
     506    20018898 :         char c = *spec_walk++;
     507    20018898 :         int check_null = 0;
     508    20018898 :         zval *real_arg = arg;
     509             : 
     510             :         /* scan through modifiers */
     511    20018898 :         ZVAL_DEREF(arg);
     512             :         while (1) {
     513    26142775 :                 if (*spec_walk == '/') {
     514     4494296 :                         SEPARATE_ZVAL(arg);
     515     2672830 :                         real_arg = arg;
     516    23469945 :                 } else if (*spec_walk == '!') {
     517     3451047 :                         check_null = 1;
     518             :                 } else {
     519    20018898 :                         break;
     520             :                 }
     521     6123877 :                 spec_walk++;
     522     6123877 :         }
     523             : 
     524    20018898 :         switch (c) {
     525             :                 case 'l':
     526             :                 case 'L':
     527             :                         {
     528     4397346 :                                 zend_long *p = va_arg(*va, zend_long *);
     529     4397346 :                                 zend_bool *is_null = NULL;
     530             : 
     531     4397346 :                                 if (check_null) {
     532          50 :                                         is_null = va_arg(*va, zend_bool *);
     533             :                                 }
     534             : 
     535     8794692 :                                 if (!zend_parse_arg_long(arg, p, is_null, check_null, c == 'L')) {
     536        1969 :                                         return "integer";
     537             :                                 }
     538             :                         }
     539     4395377 :                         break;
     540             : 
     541             :                 case 'd':
     542             :                         {
     543        3847 :                                 double *p = va_arg(*va, double *);
     544        3847 :                                 zend_bool *is_null = NULL;
     545             : 
     546        3847 :                                 if (check_null) {
     547           0 :                                         is_null = va_arg(*va, zend_bool *);
     548             :                                 }
     549             : 
     550        3847 :                                 if (!zend_parse_arg_double(arg, p, is_null, check_null)) {
     551         317 :                                         return "float";
     552             :                                 }
     553             :                         }
     554        3530 :                         break;
     555             : 
     556             :                 case 's':
     557             :                         {
     558     1921839 :                                 char **p = va_arg(*va, char **);
     559     1921839 :                                 size_t *pl = va_arg(*va, size_t *);
     560     1921839 :                                 if (!zend_parse_arg_string(arg, p, pl, check_null)) {
     561         658 :                                         return "string";
     562             :                                 }
     563             :                         }
     564     1921181 :                         break;
     565             : 
     566             :                 case 'p':
     567             :                         {
     568      291405 :                                 char **p = va_arg(*va, char **);
     569      291405 :                                 size_t *pl = va_arg(*va, size_t *);
     570      291405 :                                 if (!zend_parse_arg_path(arg, p, pl, check_null)) {
     571         134 :                                         return "a valid path";
     572             :                                 }
     573             :                         }
     574      291271 :                         break;
     575             : 
     576             :                 case 'P':
     577             :                         {
     578         354 :                                 zend_string **str = va_arg(*va, zend_string **);
     579         354 :                                 if (!zend_parse_arg_path_str(arg, str, check_null)) {
     580           4 :                                         return "a valid path";
     581             :                                 }
     582             :                         }
     583         350 :                         break;
     584             : 
     585             :                 case 'S':
     586             :                         {
     587     1284809 :                                 zend_string **str = va_arg(*va, zend_string **);
     588     1284809 :                                 if (!zend_parse_arg_str(arg, str, check_null)) {
     589         337 :                                         return "string";
     590             :                                 }
     591             :                         }
     592     1284472 :                         break;
     593             : 
     594             :                 case 'b':
     595             :                         {
     596      219303 :                                 zend_bool *p = va_arg(*va, zend_bool *);
     597      219303 :                                 zend_bool *is_null = NULL;
     598             : 
     599      219303 :                                 if (check_null) {
     600           0 :                                         is_null = va_arg(*va, zend_bool *);
     601             :                                 }
     602             : 
     603      219303 :                                 if (!zend_parse_arg_bool(arg, p, is_null, check_null)) {
     604         130 :                                         return "boolean";
     605             :                                 }
     606             :                         }
     607      219173 :                         break;
     608             : 
     609             :                 case 'r':
     610             :                         {
     611     4552692 :                                 zval **p = va_arg(*va, zval **);
     612             : 
     613     4552692 :                                 if (!zend_parse_arg_resource(arg, p, check_null)) {
     614        1686 :                                         return "resource";
     615             :                                 }
     616             :                         }
     617     4551006 :                         break;
     618             : 
     619             :                 case 'A':
     620             :                 case 'a':
     621             :                         {
     622     2686349 :                                 zval **p = va_arg(*va, zval **);
     623             : 
     624     5372698 :                                 if (!zend_parse_arg_array(arg, p, check_null, c == 'A')) {
     625        1030 :                                         return "array";
     626             :                                 }
     627             :                         }
     628     2685319 :                         break;
     629             : 
     630             :                 case 'H':
     631             :                 case 'h':
     632             :                         {
     633         217 :                                 HashTable **p = va_arg(*va, HashTable **);
     634             : 
     635         434 :                                 if (!zend_parse_arg_array_ht(arg, p, check_null, c == 'H')) {
     636          50 :                                         return "array";
     637             :                                 }
     638             :                         }
     639         167 :                         break;
     640             : 
     641             :                 case 'o':
     642             :                         {
     643       33386 :                                 zval **p = va_arg(*va, zval **);
     644             : 
     645       33386 :                                 if (!zend_parse_arg_object(arg, p, NULL, check_null)) {
     646         102 :                                         return "object";
     647             :                                 }
     648             :                         }
     649       33284 :                         break;
     650             : 
     651             :                 case 'O':
     652             :                         {
     653      687976 :                                 zval **p = va_arg(*va, zval **);
     654      687976 :                                 zend_class_entry *ce = va_arg(*va, zend_class_entry *);
     655             : 
     656      687976 :                                 if (!zend_parse_arg_object(arg, p, ce, check_null)) {
     657         810 :                                         if (ce) {
     658         810 :                                                 return ce->name->val;
     659             :                                         } else {
     660           0 :                                                 return "object";
     661             :                                         }
     662             :                                 }
     663             :                         }
     664      687166 :                         break;
     665             : 
     666             :                 case 'C':
     667             :                         {
     668          42 :                                 zend_class_entry *lookup, **pce = va_arg(*va, zend_class_entry **);
     669          42 :                                 zend_class_entry *ce_base = *pce;
     670             : 
     671          53 :                                 if (check_null && Z_TYPE_P(arg) == IS_NULL) {
     672           3 :                                         *pce = NULL;
     673           3 :                                         break;
     674             :                                 }
     675          39 :                                 convert_to_string_ex(arg);
     676          39 :                                 if ((lookup = zend_lookup_class(Z_STR_P(arg))) == NULL) {
     677           2 :                                         *pce = NULL;
     678             :                                 } else {
     679          37 :                                         *pce = lookup;
     680             :                                 }
     681          39 :                                 if (ce_base) {
     682          37 :                                         if ((!*pce || !instanceof_function(*pce, ce_base))) {
     683          18 :                                                 zend_spprintf(error, 0, "to be a class name derived from %s, '%s' given",
     684          18 :                                                         ce_base->name->val, Z_STRVAL_P(arg));
     685           9 :                                                 *pce = NULL;
     686           9 :                                                 return "";
     687             :                                         }
     688             :                                 }
     689          30 :                                 if (!*pce) {
     690           0 :                                         zend_spprintf(error, 0, "to be a valid class name, '%s' given",
     691           0 :                                                 Z_STRVAL_P(arg));
     692           0 :                                         return "";
     693             :                                 }
     694          30 :                                 break;
     695             : 
     696             :                         }
     697             :                         break;
     698             : 
     699             :                 case 'f':
     700             :                         {
     701        2230 :                                 zend_fcall_info *fci = va_arg(*va, zend_fcall_info *);
     702        2230 :                                 zend_fcall_info_cache *fcc = va_arg(*va, zend_fcall_info_cache *);
     703        2230 :                                 char *is_callable_error = NULL;
     704             : 
     705        2236 :                                 if (check_null && Z_TYPE_P(arg) == IS_NULL) {
     706           1 :                                         fci->size = 0;
     707           1 :                                         fcc->initialized = 0;
     708           1 :                                         break;
     709             :                                 }
     710             : 
     711        2229 :                                 if (zend_fcall_info_init(arg, 0, fci, fcc, NULL, &is_callable_error) == SUCCESS) {
     712        1633 :                                         if (is_callable_error) {
     713           0 :                                                 *severity = E_DEPRECATED;
     714           0 :                                                 zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error);
     715           0 :                                                 efree(is_callable_error);
     716           0 :                                                 *spec = spec_walk;
     717           0 :                                                 return "";
     718             :                                         }
     719        1633 :                                         break;
     720             :                                 } else {
     721         596 :                                         if (is_callable_error) {
     722         596 :                                                 *severity = E_EXCEPTION | E_ERROR;
     723         596 :                                                 zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error);
     724         596 :                                                 efree(is_callable_error);
     725         596 :                                                 return "";
     726             :                                         } else {
     727           0 :                                                 return "valid callback";
     728             :                                         }
     729             :                                 }
     730             :                         }
     731             : 
     732             :                 case 'z':
     733             :                         {
     734     3937103 :                                 zval **p = va_arg(*va, zval **);
     735             : 
     736             :                                 zend_parse_arg_zval_deref(real_arg, p, check_null);
     737             :                         }
     738     3937103 :                         break;
     739             : 
     740             :                 case 'Z':
     741             :                         /* 'Z' iz not supported anymore and should be replaced with 'z' */
     742             :                         ZEND_ASSERT(c != 'Z');
     743             :                 default:
     744           0 :                         return "unknown";
     745             :         }
     746             : 
     747    20011066 :         *spec = spec_walk;
     748             : 
     749    20011066 :         return NULL;
     750             : }
     751             : /* }}} */
     752             : 
     753    20018898 : static int zend_parse_arg(int arg_num, zval *arg, va_list *va, const char **spec, int flags) /* {{{ */
     754             : {
     755    20018898 :         const char *expected_type = NULL;
     756    20018898 :         char *error = NULL;
     757    20018898 :         int severity = 0;
     758             : 
     759    20018898 :         expected_type = zend_parse_arg_impl(arg_num, arg, va, spec, &error, &severity);
     760    20018898 :         if (expected_type) {
     761        7832 :                 if (!(flags & ZEND_PARSE_PARAMS_QUIET) && (*expected_type || error)) {
     762             :                         const char *space;
     763        7050 :                         const char *class_name = get_active_class_name(&space);
     764             :                         zend_bool throw_exception =
     765        7050 :                                 ZEND_ARG_USES_STRICT_TYPES() || (flags & ZEND_PARSE_PARAMS_THROW);
     766             : 
     767        7050 :                         if (error) {
     768         605 :                                 zend_internal_type_error(throw_exception, "%s%s%s() expects parameter %d %s",
     769             :                                                 class_name, space, get_active_function_name(), arg_num, error);
     770         605 :                                 efree(error);
     771             :                         } else {
     772        6445 :                                 zend_internal_type_error(throw_exception,
     773             :                                                 "%s%s%s() expects parameter %d to be %s, %s given",
     774             :                                                 class_name, space, get_active_function_name(), arg_num, expected_type,
     775             :                                                 zend_zval_type_name(arg));
     776             :                         }
     777             :                 }
     778        7832 :                 if (severity != E_DEPRECATED) {
     779        7832 :                         return FAILURE;
     780             :                 }
     781             :         }
     782             : 
     783    20011066 :         return SUCCESS;
     784             : }
     785             : /* }}} */
     786             : 
     787           0 : ZEND_API int zend_parse_parameter(int flags, int arg_num, zval *arg, const char *spec, ...)
     788             : {
     789             :         va_list va;
     790             :         int ret;
     791             : 
     792           0 :         va_start(va, spec);
     793           0 :         ret = zend_parse_arg(arg_num, arg, &va, &spec, flags);
     794           0 :         va_end(va);
     795             : 
     796           0 :         return ret;
     797             : }
     798             : 
     799           0 : static void zend_parse_parameters_debug_error(const char *msg) {
     800           0 :         zend_function *active_function = EG(current_execute_data)->func;
     801           0 :         const char *class_name = active_function->common.scope
     802           0 :                 ? active_function->common.scope->name->val : "";
     803           0 :         zend_error_noreturn(E_CORE_ERROR, "%s%s%s(): %s",
     804           0 :                 class_name, class_name[0] ? "::" : "",
     805           0 :                 active_function->common.function_name->val, msg);
     806             : }
     807             : 
     808    12761296 : static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, int flags) /* {{{ */
     809             : {
     810             :         const  char *spec_walk;
     811             :         int c, i;
     812    12761296 :         int min_num_args = -1;
     813    12761296 :         int max_num_args = 0;
     814    12761296 :         int post_varargs = 0;
     815             :         zval *arg;
     816             :         int arg_count;
     817    12761296 :         zend_bool have_varargs = 0;
     818    12761296 :         zval **varargs = NULL;
     819    12761296 :         int *n_varargs = NULL;
     820             : 
     821    48296546 :         for (spec_walk = type_spec; *spec_walk; spec_walk++) {
     822    35535250 :                 c = *spec_walk;
     823    35535250 :                 switch (c) {
     824             :                         case 'l': case 'd':
     825             :                         case 's': case 'b':
     826             :                         case 'r': case 'a':
     827             :                         case 'o': case 'O':
     828             :                         case 'z': case 'Z':
     829             :                         case 'C': case 'h':
     830             :                         case 'f': case 'A':
     831             :                         case 'H': case 'p':
     832             :                         case 'S': case 'P':
     833             :                         case 'L':
     834    24291182 :                                 max_num_args++;
     835    24291182 :                                 break;
     836             : 
     837             :                         case '|':
     838     4736466 :                                 min_num_args = max_num_args;
     839     4736466 :                                 break;
     840             : 
     841             :                         case '/':
     842             :                         case '!':
     843             :                                 /* Pass */
     844     6191052 :                                 break;
     845             : 
     846             :                         case '*':
     847             :                         case '+':
     848      316550 :                                 if (have_varargs) {
     849           0 :                                         zend_parse_parameters_debug_error(
     850             :                                                 "only one varargs specifier (* or +) is permitted");
     851           0 :                                         return FAILURE;
     852             :                                 }
     853      316550 :                                 have_varargs = 1;
     854             :                                 /* we expect at least one parameter in varargs */
     855      316550 :                                 if (c == '+') {
     856      309061 :                                         max_num_args++;
     857             :                                 }
     858             :                                 /* mark the beginning of varargs */
     859      316550 :                                 post_varargs = max_num_args;
     860      316550 :                                 break;
     861             : 
     862             :                         default:
     863           0 :                                 zend_parse_parameters_debug_error("bad type specifier while parsing parameters");
     864           0 :                                 return FAILURE;
     865             :                 }
     866             :         }
     867             : 
     868    12761296 :         if (min_num_args < 0) {
     869     8024830 :                 min_num_args = max_num_args;
     870             :         }
     871             : 
     872    12761296 :         if (have_varargs) {
     873             :                 /* calculate how many required args are at the end of the specifier list */
     874      316550 :                 post_varargs = max_num_args - post_varargs;
     875      316550 :                 max_num_args = -1;
     876             :         }
     877             : 
     878    12761296 :         if (num_args < min_num_args || (num_args > max_num_args && max_num_args > 0)) {
     879        2006 :                 if (!(flags & ZEND_PARSE_PARAMS_QUIET)) {
     880        1862 :                         zend_function *active_function = EG(current_execute_data)->func;
     881        1862 :                         const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
     882             :                         zend_bool throw_exception =
     883        1862 :                                 ZEND_ARG_USES_STRICT_TYPES() || (flags & ZEND_PARSE_PARAMS_THROW);
     884        5586 :                         zend_internal_type_error(throw_exception, "%s%s%s() expects %s %d parameter%s, %d given",
     885             :                                         class_name,
     886        1862 :                                         class_name[0] ? "::" : "",
     887        1862 :                                         active_function->common.function_name->val,
     888             :                                         min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
     889             :                                         num_args < min_num_args ? min_num_args : max_num_args,
     890             :                                         (num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
     891             :                                         num_args);
     892             :                 }
     893        2006 :                 return FAILURE;
     894             :         }
     895             : 
     896    12759290 :         arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
     897             : 
     898    12759290 :         if (num_args > arg_count) {
     899           0 :                 zend_parse_parameters_debug_error("could not obtain parameters for parsing");
     900           0 :                 return FAILURE;
     901             :         }
     902             : 
     903    12759290 :         i = 0;
     904    45838667 :         while (num_args-- > 0) {
     905    20327919 :                 if (*type_spec == '|') {
     906      645532 :                         type_spec++;
     907             :                 }
     908             : 
     909    20327919 :                 if (*type_spec == '*' || *type_spec == '+') {
     910      309021 :                         int num_varargs = num_args + 1 - post_varargs;
     911             : 
     912             :                         /* eat up the passed in storage even if it won't be filled in with varargs */
     913      309021 :                         varargs = va_arg(*va, zval **);
     914      309021 :                         n_varargs = va_arg(*va, int *);
     915      309021 :                         type_spec++;
     916             : 
     917      309021 :                         if (num_varargs > 0) {
     918      309021 :                                 *n_varargs = num_varargs;
     919      309021 :                                 *varargs = ZEND_CALL_ARG(EG(current_execute_data), i + 1);
     920             :                                 /* adjust how many args we have left and restart loop */
     921      309021 :                                 num_args += 1 - num_varargs;
     922      309021 :                                 i += num_varargs;
     923      309021 :                                 continue;
     924             :                         } else {
     925           0 :                                 *varargs = NULL;
     926           0 :                                 *n_varargs = 0;
     927             :                         }
     928             :                 }
     929             : 
     930    20018898 :                 arg = ZEND_CALL_ARG(EG(current_execute_data), i + 1);
     931             : 
     932    20018898 :                 if (zend_parse_arg(i+1, arg, va, &type_spec, flags) == FAILURE) {
     933             :                         /* clean up varargs array if it was used */
     934        7832 :                         if (varargs && *varargs) {
     935         418 :                                 *varargs = NULL;
     936             :                         }
     937        7832 :                         return FAILURE;
     938             :                 }
     939    20011066 :                 i++;
     940             :         }
     941             : 
     942    12751458 :         return SUCCESS;
     943             : }
     944             : /* }}} */
     945             : 
     946             : #define RETURN_IF_ZERO_ARGS(num_args, type_spec, flags) do { \
     947             :         int __num_args = (num_args); \
     948             :         if (0 == (type_spec)[0] && 0 != __num_args && !(flags & ZEND_PARSE_PARAMS_QUIET)) { \
     949             :                 const char *__space; \
     950             :                 const char * __class_name = get_active_class_name(&__space); \
     951             :                 zend_bool throw_exception = \
     952             :                         ZEND_ARG_USES_STRICT_TYPES() || (flags & ZEND_PARSE_PARAMS_THROW); \
     953             :                 zend_internal_type_error(throw_exception, \
     954             :                         "%s%s%s() expects exactly 0 parameters, %d given", \
     955             :                         __class_name, __space, get_active_function_name(), __num_args); \
     956             :                 return FAILURE; \
     957             :         } \
     958             : } while(0)
     959             : 
     960        9285 : ZEND_API int zend_parse_parameters_ex(int flags, int num_args, const char *type_spec, ...) /* {{{ */
     961             : {
     962             :         va_list va;
     963             :         int retval;
     964             : 
     965        9285 :         RETURN_IF_ZERO_ARGS(num_args, type_spec, flags);
     966             : 
     967        9285 :         va_start(va, type_spec);
     968        9285 :         retval = zend_parse_va_args(num_args, type_spec, &va, flags);
     969        9285 :         va_end(va);
     970             : 
     971        9285 :         return retval;
     972             : }
     973             : /* }}} */
     974             : 
     975    11867443 : ZEND_API int zend_parse_parameters(int num_args, const char *type_spec, ...) /* {{{ */
     976             : {
     977             :         va_list va;
     978             :         int retval;
     979    11867443 :         int flags = 0;
     980             : 
     981    11867443 :         RETURN_IF_ZERO_ARGS(num_args, type_spec, flags);
     982             : 
     983    11867091 :         va_start(va, type_spec);
     984    11867091 :         retval = zend_parse_va_args(num_args, type_spec, &va, flags);
     985    11867091 :         va_end(va);
     986             : 
     987    11867091 :         return retval;
     988             : }
     989             : /* }}} */
     990             : 
     991      186924 : ZEND_API int zend_parse_parameters_throw(int num_args, const char *type_spec, ...) /* {{{ */
     992             : {
     993             :         va_list va;
     994             :         int retval;
     995      186924 :         int flags = ZEND_PARSE_PARAMS_THROW;
     996             : 
     997      186924 :         RETURN_IF_ZERO_ARGS(num_args, type_spec, flags);
     998             : 
     999      186923 :         va_start(va, type_spec);
    1000      186923 :         retval = zend_parse_va_args(num_args, type_spec, &va, flags);
    1001      186923 :         va_end(va);
    1002             : 
    1003      186923 :         return retval;
    1004             : }
    1005             : /* }}} */
    1006             : 
    1007      698028 : ZEND_API int zend_parse_method_parameters(int num_args, zval *this_ptr, const char *type_spec, ...) /* {{{ */
    1008             : {
    1009             :         va_list va;
    1010             :         int retval;
    1011      698028 :         int flags = 0;
    1012      698028 :         const char *p = type_spec;
    1013             :         zval **object;
    1014             :         zend_class_entry *ce;
    1015             : 
    1016             :         /* Just checking this_ptr is not enough, because fcall_common_helper does not set
    1017             :          * Z_OBJ(EG(This)) to NULL when calling an internal function with common.scope == NULL.
    1018             :          * In that case EG(This) would still be the $this from the calling code and we'd take the
    1019             :          * wrong branch here. */
    1020      698028 :         zend_bool is_method = EG(current_execute_data)->func->common.scope != NULL;
    1021             : 
    1022     1396056 :         if (!is_method || !this_ptr || Z_TYPE_P(this_ptr) != IS_OBJECT) {
    1023      338327 :                 RETURN_IF_ZERO_ARGS(num_args, p, flags);
    1024             : 
    1025      338327 :                 va_start(va, type_spec);
    1026      338327 :                 retval = zend_parse_va_args(num_args, type_spec, &va, flags);
    1027      338327 :                 va_end(va);
    1028             :         } else {
    1029      359701 :                 p++;
    1030      359701 :                 RETURN_IF_ZERO_ARGS(num_args, p, flags);
    1031             : 
    1032      359670 :                 va_start(va, type_spec);
    1033             : 
    1034      359670 :                 object = va_arg(va, zval **);
    1035      359670 :                 ce = va_arg(va, zend_class_entry *);
    1036      359670 :                 *object = this_ptr;
    1037             : 
    1038      359670 :                 if (ce && !instanceof_function(Z_OBJCE_P(this_ptr), ce)) {
    1039           0 :                         zend_error_noreturn(E_CORE_ERROR, "%s::%s() must be derived from %s::%s",
    1040           0 :                                 Z_OBJCE_P(this_ptr)->name->val, get_active_function_name(), ce->name->val, get_active_function_name());
    1041             :                 }
    1042             : 
    1043      359670 :                 retval = zend_parse_va_args(num_args, p, &va, flags);
    1044      359670 :                 va_end(va);
    1045             :         }
    1046      697997 :         return retval;
    1047             : }
    1048             : /* }}} */
    1049             : 
    1050           0 : ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this_ptr, const char *type_spec, ...) /* {{{ */
    1051             : {
    1052             :         va_list va;
    1053             :         int retval;
    1054           0 :         const char *p = type_spec;
    1055             :         zval **object;
    1056             :         zend_class_entry *ce;
    1057             : 
    1058           0 :         if (!this_ptr) {
    1059           0 :                 RETURN_IF_ZERO_ARGS(num_args, p, flags);
    1060             : 
    1061           0 :                 va_start(va, type_spec);
    1062           0 :                 retval = zend_parse_va_args(num_args, type_spec, &va, flags);
    1063           0 :                 va_end(va);
    1064             :         } else {
    1065           0 :                 p++;
    1066           0 :                 RETURN_IF_ZERO_ARGS(num_args, p, flags);
    1067             : 
    1068           0 :                 va_start(va, type_spec);
    1069             : 
    1070           0 :                 object = va_arg(va, zval **);
    1071           0 :                 ce = va_arg(va, zend_class_entry *);
    1072           0 :                 *object = this_ptr;
    1073             : 
    1074           0 :                 if (ce && !instanceof_function(Z_OBJCE_P(this_ptr), ce)) {
    1075           0 :                         if (!(flags & ZEND_PARSE_PARAMS_QUIET)) {
    1076           0 :                                 zend_error_noreturn(E_CORE_ERROR, "%s::%s() must be derived from %s::%s",
    1077           0 :                                         ce->name->val, get_active_function_name(), Z_OBJCE_P(this_ptr)->name->val, get_active_function_name());
    1078             :                         }
    1079           0 :                         va_end(va);
    1080           0 :                         return FAILURE;
    1081             :                 }
    1082             : 
    1083           0 :                 retval = zend_parse_va_args(num_args, p, &va, flags);
    1084           0 :                 va_end(va);
    1085             :         }
    1086           0 :         return retval;
    1087             : }
    1088             : /* }}} */
    1089             : 
    1090             : /* Argument parsing API -- andrei */
    1091     2204766 : ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC) /* {{{ */
    1092             : {
    1093     2204766 :         ZVAL_NEW_ARR(arg);
    1094     2204766 :         _zend_hash_init(Z_ARRVAL_P(arg), size, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);
    1095     2204766 :         return SUCCESS;
    1096             : }
    1097             : /* }}} */
    1098             : 
    1099             : /* This function should be called after the constructor has been called
    1100             :  * because it may call __set from the uninitialized object otherwise. */
    1101           9 : ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */
    1102             : {
    1103           9 :         const zend_object_handlers *obj_ht = Z_OBJ_HT_P(obj);
    1104           9 :         zend_class_entry *old_scope = EG(scope);
    1105             :         zend_string *key;
    1106             :         zval *value;
    1107             : 
    1108           9 :         EG(scope) = Z_OBJCE_P(obj);
    1109          45 :         ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, value) {
    1110          18 :                 if (key) {
    1111             :                         zval member;
    1112             : 
    1113          18 :                         ZVAL_STR(&member, key);
    1114          18 :                         obj_ht->write_property(obj, &member, value, NULL);
    1115             :                 }
    1116             :         } ZEND_HASH_FOREACH_END();
    1117           9 :         EG(scope) = old_scope;
    1118           9 : }
    1119             : /* }}} */
    1120             : 
    1121          80 : static int zval_update_class_constant(zval *pp, int is_static, uint32_t offset) /* {{{ */
    1122             : {
    1123          80 :         ZVAL_DEREF(pp);
    1124          80 :         if (Z_CONSTANT_P(pp)) {
    1125          65 :                 zend_class_entry **scope = EG(current_execute_data) ? &EG(scope) : &CG(active_class_entry);
    1126             : 
    1127          65 :                 if ((*scope)->parent) {
    1128          11 :                         zend_class_entry *ce = *scope;
    1129             :                         zend_property_info *prop_info;
    1130             : 
    1131             :                         do {
    1132          66 :                                 ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
    1133          59 :                                         if (is_static == ((prop_info->flags & ZEND_ACC_STATIC) != 0) &&
    1134          26 :                                             offset == prop_info->offset) {
    1135             :                                                 int ret;
    1136          11 :                                                 zend_class_entry *old_scope = *scope;
    1137          11 :                                                 *scope = prop_info->ce;
    1138          11 :                                                 ret = zval_update_constant_ex(pp, 1, NULL);
    1139          11 :                                                 *scope = old_scope;
    1140          11 :                                                 return ret;
    1141             :                                         }
    1142             :                                 } ZEND_HASH_FOREACH_END();
    1143           0 :                                 ce = ce->parent;
    1144           0 :                         } while (ce);
    1145             : 
    1146             :                 }
    1147          54 :                 return zval_update_constant_ex(pp, 1, NULL);
    1148             :         }
    1149          15 :         return SUCCESS;
    1150             : }
    1151             : /* }}} */
    1152             : 
    1153      859632 : ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
    1154             : {
    1155             :         int i;
    1156             : 
    1157             :         /* initialize static members of internal class */
    1158      859632 :         if (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count) {
    1159             :                 zval *p;
    1160             : 
    1161           0 :                 if (class_type->parent) {
    1162           0 :                         if (UNEXPECTED(zend_update_class_constants(class_type->parent) != SUCCESS)) {
    1163           0 :                                 return FAILURE;
    1164             :                         }
    1165             :                 }
    1166             : #if ZTS
    1167             :                 CG(static_members_table)[(zend_intptr_t)(class_type->static_members_table)] = emalloc(sizeof(zval) * class_type->default_static_members_count);
    1168             : #else
    1169           0 :                 class_type->static_members_table = emalloc(sizeof(zval) * class_type->default_static_members_count);
    1170             : #endif
    1171           0 :                 for (i = 0; i < class_type->default_static_members_count; i++) {
    1172           0 :                         p = &class_type->default_static_members_table[i];
    1173           0 :                         if (Z_ISREF_P(p) &&
    1174           0 :                                 class_type->parent &&
    1175           0 :                                 i < class_type->parent->default_static_members_count &&
    1176           0 :                                 p == &class_type->parent->default_static_members_table[i] &&
    1177           0 :                                 Z_TYPE(CE_STATIC_MEMBERS(class_type->parent)[i]) != IS_UNDEF
    1178             :                         ) {
    1179           0 :                                 zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i];
    1180             : 
    1181           0 :                                 ZVAL_NEW_REF(q, q);
    1182           0 :                                 ZVAL_COPY_VALUE(&CE_STATIC_MEMBERS(class_type)[i], q);
    1183             :                                 Z_ADDREF_P(q);
    1184             :                         } else {
    1185           0 :                                 ZVAL_DUP(&CE_STATIC_MEMBERS(class_type)[i], p);
    1186             :                         }
    1187             :                 }
    1188             :         }
    1189             : 
    1190      859632 :         if ((class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) == 0) {
    1191          30 :                 zend_class_entry **scope = EG(current_execute_data) ? &EG(scope) : &CG(active_class_entry);
    1192          30 :                 zend_class_entry *old_scope = *scope;
    1193             :                 zval *val;
    1194             : 
    1195          30 :                 *scope = class_type;
    1196             : 
    1197         107 :                 ZEND_HASH_FOREACH_VAL(&class_type->constants_table, val) {
    1198          39 :                         if (UNEXPECTED(zval_update_constant_ex(val, 1, class_type) != SUCCESS)) {
    1199           0 :                                 return FAILURE;
    1200             :                         }
    1201             :                 } ZEND_HASH_FOREACH_END();
    1202             : 
    1203          48 :                 for (i = 0; i < class_type->default_properties_count; i++) {
    1204          38 :                         if (Z_TYPE(class_type->default_properties_table[i]) != IS_UNDEF) {
    1205          19 :                                 if (UNEXPECTED(zval_update_class_constant(&class_type->default_properties_table[i], 0, OBJ_PROP_TO_OFFSET(i)) != SUCCESS)) {
    1206           0 :                                         return FAILURE;
    1207             :                                 }
    1208             :                         }
    1209             :                 }
    1210             : 
    1211          90 :                 for (i = 0; i < class_type->default_static_members_count; i++) {
    1212          61 :                         if (UNEXPECTED(zval_update_class_constant(&CE_STATIC_MEMBERS(class_type)[i], 1, i) != SUCCESS)) {
    1213           0 :                                 return FAILURE;
    1214             :                         }
    1215             :                 }
    1216             : 
    1217          29 :                 *scope = old_scope;
    1218          29 :                 class_type->ce_flags |= ZEND_ACC_CONSTANTS_UPDATED;
    1219             :         }
    1220      859631 :         return SUCCESS;
    1221             : }
    1222             : /* }}} */
    1223             : 
    1224     1242516 : ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type) /* {{{ */
    1225             : {
    1226     1242516 :         if (class_type->default_properties_count) {
    1227      113112 :                 zval *src = class_type->default_properties_table;
    1228      113112 :                 zval *dst = object->properties_table;
    1229      113112 :                 zval *end = src + class_type->default_properties_count;
    1230             : 
    1231             :                 do {
    1232             : #if ZTS
    1233             :                         ZVAL_DUP(dst, src);
    1234             : #else
    1235      266954 :                         ZVAL_COPY(dst, src);
    1236             : #endif
    1237      266954 :                         src++;
    1238      266954 :                         dst++;
    1239      266954 :                 } while (src != end);
    1240      113112 :                 object->properties = NULL;
    1241             :         }
    1242     1242516 : }
    1243             : /* }}} */
    1244             : 
    1245          83 : ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properties) /* {{{ */
    1246             : {
    1247          83 :         object->properties = properties;
    1248          83 :         if (object->ce->default_properties_count) {
    1249             :             zval *prop;
    1250             :         zend_string *key;
    1251             :         zend_property_info *property_info;
    1252             : 
    1253           0 :         ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, prop) {
    1254           0 :                         property_info = zend_get_property_info(object->ce, key, 1);
    1255           0 :                         if (property_info != ZEND_WRONG_PROPERTY_INFO &&
    1256             :                             property_info &&
    1257           0 :                             (property_info->flags & ZEND_ACC_STATIC) == 0) {
    1258           0 :                                 zval *slot = OBJ_PROP(object, property_info->offset);
    1259           0 :                                 ZVAL_COPY_VALUE(slot, prop);
    1260           0 :                                 ZVAL_INDIRECT(prop, slot);
    1261             :                         }
    1262             :                 } ZEND_HASH_FOREACH_END();
    1263             :         }
    1264          83 : }
    1265             : /* }}} */
    1266             : 
    1267          14 : ZEND_API void object_properties_load(zend_object *object, HashTable *properties) /* {{{ */
    1268             : {
    1269             :     zval *prop, tmp;
    1270             :         zend_string *key;
    1271             :         zend_property_info *property_info;
    1272             : 
    1273          28 :         ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, prop) {
    1274           7 :                 property_info = zend_get_property_info(object->ce, key, 1);
    1275          13 :                 if (property_info != ZEND_WRONG_PROPERTY_INFO &&
    1276             :                     property_info &&
    1277           3 :                     (property_info->flags & ZEND_ACC_STATIC) == 0) {
    1278           3 :                         zval *slot = OBJ_PROP(object, property_info->offset);
    1279           3 :                         zval_ptr_dtor(slot);
    1280           3 :                         ZVAL_COPY_VALUE(slot, prop);
    1281           3 :                         zval_add_ref(slot);
    1282           3 :                         if (object->properties) {
    1283           0 :                                 ZVAL_INDIRECT(&tmp, slot);
    1284           0 :                                 zend_hash_update(object->properties, key, &tmp);
    1285             :                         }
    1286             :                 } else {
    1287           4 :                         if (!object->properties) {
    1288           2 :                                 rebuild_object_properties(object);
    1289             :                         }
    1290           4 :                         prop = zend_hash_update(object->properties, key, prop);
    1291           4 :                         zval_add_ref(prop);
    1292             :                 }
    1293             :         } ZEND_HASH_FOREACH_END();
    1294          14 : }
    1295             : /* }}} */
    1296             : 
    1297             : /* This function requires 'properties' to contain all props declared in the
    1298             :  * class and all props being public. If only a subset is given or the class
    1299             :  * has protected members then you need to merge the properties separately by
    1300             :  * calling zend_merge_properties(). */
    1301      852029 : ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC) /* {{{ */
    1302             : {
    1303      852029 :         if (UNEXPECTED(class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
    1304           9 :                 if (class_type->ce_flags & ZEND_ACC_INTERFACE) {
    1305           2 :                         zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate interface %s", class_type->name->val);
    1306           7 :                 } else if (class_type->ce_flags & ZEND_ACC_TRAIT) {
    1307           2 :                         zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate trait %s", class_type->name->val);
    1308             :                 } else {
    1309           5 :                         zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate abstract class %s", class_type->name->val);
    1310             :                 }
    1311           9 :                 ZVAL_NULL(arg);
    1312           9 :                 Z_OBJ_P(arg) = NULL;
    1313           9 :                 return FAILURE;
    1314             :         }
    1315             : 
    1316      852020 :         if (UNEXPECTED(zend_update_class_constants(class_type) != SUCCESS)) {
    1317           0 :                 ZVAL_NULL(arg);
    1318           0 :                 Z_OBJ_P(arg) = NULL;
    1319           0 :                 return FAILURE;
    1320             :         }
    1321             : 
    1322      852019 :         if (class_type->create_object == NULL) {
    1323      428015 :                 ZVAL_OBJ(arg, zend_objects_new(class_type));
    1324      428015 :                 if (properties) {
    1325          83 :                         object_properties_init_ex(Z_OBJ_P(arg), properties);
    1326             :                 } else {
    1327      427932 :                         object_properties_init(Z_OBJ_P(arg), class_type);
    1328             :                 }
    1329             :         } else {
    1330      424004 :                 ZVAL_OBJ(arg, class_type->create_object(class_type));
    1331             :         }
    1332      852019 :         return SUCCESS;
    1333             : }
    1334             : /* }}} */
    1335             : 
    1336      851872 : ZEND_API int _object_init_ex(zval *arg, zend_class_entry *class_type ZEND_FILE_LINE_DC) /* {{{ */
    1337             : {
    1338      851872 :         return _object_and_properties_init(arg, class_type, 0 ZEND_FILE_LINE_RELAY_CC);
    1339             : }
    1340             : /* }}} */
    1341             : 
    1342        1630 : ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC) /* {{{ */
    1343             : {
    1344        1630 :         return _object_init_ex(arg, zend_standard_class_def ZEND_FILE_LINE_RELAY_CC);
    1345             : }
    1346             : /* }}} */
    1347             : 
    1348           0 : ZEND_API int add_assoc_function(zval *arg, const char *key, void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS)) /* {{{ */
    1349             : {
    1350           0 :         zend_error(E_WARNING, "add_assoc_function() is no longer supported");
    1351           0 :         return FAILURE;
    1352             : }
    1353             : /* }}} */
    1354             : 
    1355      126897 : ZEND_API int add_assoc_long_ex(zval *arg, const char *key, size_t key_len, zend_long n) /* {{{ */
    1356             : {
    1357             :         zval *ret, tmp;
    1358             : 
    1359      126897 :         ZVAL_LONG(&tmp, n);
    1360      253794 :         ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
    1361      126897 :         return ret ? SUCCESS : FAILURE;
    1362             : }
    1363             : /* }}} */
    1364             : 
    1365         951 : ZEND_API int add_assoc_null_ex(zval *arg, const char *key, size_t key_len) /* {{{ */
    1366             : {
    1367             :         zval *ret, tmp;
    1368             : 
    1369         951 :         ZVAL_NULL(&tmp);
    1370        1902 :         ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
    1371         951 :         return ret ? SUCCESS : FAILURE;
    1372             : }
    1373             : /* }}} */
    1374             : 
    1375       84929 : ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, size_t key_len, int b) /* {{{ */
    1376             : {
    1377             :         zval *ret, tmp;
    1378             : 
    1379       84929 :         ZVAL_BOOL(&tmp, b);
    1380      169858 :         ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
    1381       84929 :         return ret ? SUCCESS : FAILURE;
    1382             : }
    1383             : /* }}} */
    1384             : 
    1385           0 : ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, size_t key_len, zend_resource *r) /* {{{ */
    1386             : {
    1387             :         zval *ret, tmp;
    1388             : 
    1389           0 :         ZVAL_RES(&tmp, r);
    1390           0 :         ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
    1391           0 :         return ret ? SUCCESS : FAILURE;
    1392             : }
    1393             : /* }}} */
    1394             : 
    1395         194 : ZEND_API int add_assoc_double_ex(zval *arg, const char *key, size_t key_len, double d) /* {{{ */
    1396             : {
    1397             :         zval *ret, tmp;
    1398             : 
    1399         194 :         ZVAL_DOUBLE(&tmp, d);
    1400         388 :         ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
    1401         194 :         return ret ? SUCCESS : FAILURE;
    1402             : }
    1403             : /* }}} */
    1404             : 
    1405       10693 : ZEND_API int add_assoc_str_ex(zval *arg, const char *key, size_t key_len, zend_string *str) /* {{{ */
    1406             : {
    1407             :         zval *ret, tmp;
    1408             : 
    1409       10693 :         ZVAL_STR(&tmp, str);
    1410       21386 :         ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
    1411       10693 :         return ret ? SUCCESS : FAILURE;
    1412             : }
    1413             : /* }}} */
    1414             : 
    1415       77600 : ZEND_API int add_assoc_string_ex(zval *arg, const char *key, size_t key_len, char *str) /* {{{ */
    1416             : {
    1417             :         zval *ret, tmp;
    1418             : 
    1419      155200 :         ZVAL_STRING(&tmp, str);
    1420      155200 :         ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
    1421       77600 :         return ret ? SUCCESS : FAILURE;
    1422             : }
    1423             : /* }}} */
    1424             : 
    1425       10669 : ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, size_t key_len, char *str, size_t length) /* {{{ */
    1426             : {
    1427             :         zval *ret, tmp;
    1428             : 
    1429       21338 :         ZVAL_STRINGL(&tmp, str, length);
    1430       21338 :         ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
    1431       10669 :         return ret ? SUCCESS : FAILURE;
    1432             : }
    1433             : /* }}} */
    1434             : 
    1435        7442 : ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, size_t key_len, zval *value) /* {{{ */
    1436             : {
    1437             :         zval *ret;
    1438             : 
    1439       14884 :         ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, value);
    1440        7442 :         return ret ? SUCCESS : FAILURE;
    1441             : }
    1442             : /* }}} */
    1443             : 
    1444       12527 : ZEND_API int add_index_long(zval *arg, zend_ulong index, zend_long n) /* {{{ */
    1445             : {
    1446             :         zval tmp;
    1447             : 
    1448       12527 :         ZVAL_LONG(&tmp, n);
    1449       12527 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
    1450             : }
    1451             : /* }}} */
    1452             : 
    1453       16892 : ZEND_API int add_index_null(zval *arg, zend_ulong index) /* {{{ */
    1454             : {
    1455             :         zval tmp;
    1456             : 
    1457       16892 :         ZVAL_NULL(&tmp);
    1458       16892 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
    1459             : }
    1460             : /* }}} */
    1461             : 
    1462         490 : ZEND_API int add_index_bool(zval *arg, zend_ulong index, int b) /* {{{ */
    1463             : {
    1464             :         zval tmp;
    1465             : 
    1466         490 :         ZVAL_BOOL(&tmp, b);
    1467         490 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
    1468             : }
    1469             : /* }}} */
    1470             : 
    1471           0 : ZEND_API int add_index_resource(zval *arg, zend_ulong index, zend_resource *r) /* {{{ */
    1472             : {
    1473             :         zval tmp;
    1474             : 
    1475           0 :         ZVAL_RES(&tmp, r);
    1476           0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
    1477             : }
    1478             : /* }}} */
    1479             : 
    1480         764 : ZEND_API int add_index_double(zval *arg, zend_ulong index, double d) /* {{{ */
    1481             : {
    1482             :         zval tmp;
    1483             : 
    1484         764 :         ZVAL_DOUBLE(&tmp, d);
    1485         764 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
    1486             : }
    1487             : /* }}} */
    1488             : 
    1489          93 : ZEND_API int add_index_str(zval *arg, zend_ulong index, zend_string *str) /* {{{ */
    1490             : {
    1491             :         zval tmp;
    1492             : 
    1493          93 :         ZVAL_STR(&tmp, str);
    1494          93 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
    1495             : }
    1496             : /* }}} */
    1497             : 
    1498         943 : ZEND_API int add_index_string(zval *arg, zend_ulong index, const char *str) /* {{{ */
    1499             : {
    1500             :         zval tmp;
    1501             : 
    1502        1886 :         ZVAL_STRING(&tmp, str);
    1503         943 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
    1504             : }
    1505             : /* }}} */
    1506             : 
    1507       37242 : ZEND_API int add_index_stringl(zval *arg, zend_ulong index, const char *str, size_t length) /* {{{ */
    1508             : {
    1509             :         zval tmp;
    1510             : 
    1511       74484 :         ZVAL_STRINGL(&tmp, str, length);
    1512       37242 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
    1513             : }
    1514             : /* }}} */
    1515             : 
    1516       64027 : ZEND_API int add_index_zval(zval *arg, zend_ulong index, zval *value) /* {{{ */
    1517             : {
    1518       64027 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, value) ? SUCCESS : FAILURE;
    1519             : }
    1520             : /* }}} */
    1521             : 
    1522        3941 : ZEND_API int add_next_index_long(zval *arg, zend_long n) /* {{{ */
    1523             : {
    1524             :         zval tmp;
    1525             : 
    1526        3941 :         ZVAL_LONG(&tmp, n);
    1527        3941 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
    1528             : }
    1529             : /* }}} */
    1530             : 
    1531        1038 : ZEND_API int add_next_index_null(zval *arg) /* {{{ */
    1532             : {
    1533             :         zval tmp;
    1534             : 
    1535        1038 :         ZVAL_NULL(&tmp);
    1536        1038 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
    1537             : }
    1538             : /* }}} */
    1539             : 
    1540           0 : ZEND_API int add_next_index_bool(zval *arg, int b) /* {{{ */
    1541             : {
    1542             :         zval tmp;
    1543             : 
    1544           0 :         ZVAL_BOOL(&tmp, b);
    1545           0 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
    1546             : }
    1547             : /* }}} */
    1548             : 
    1549          16 : ZEND_API int add_next_index_resource(zval *arg, zend_resource *r) /* {{{ */
    1550             : {
    1551             :         zval tmp;
    1552             : 
    1553          16 :         ZVAL_RES(&tmp, r);
    1554          16 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
    1555             : }
    1556             : /* }}} */
    1557             : 
    1558           0 : ZEND_API int add_next_index_double(zval *arg, double d) /* {{{ */
    1559             : {
    1560             :         zval tmp;
    1561             : 
    1562           0 :         ZVAL_DOUBLE(&tmp, d);
    1563           0 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
    1564             : }
    1565             : /* }}} */
    1566             : 
    1567       13303 : ZEND_API int add_next_index_str(zval *arg, zend_string *str) /* {{{ */
    1568             : {
    1569             :         zval tmp;
    1570             : 
    1571       13303 :         ZVAL_STR(&tmp, str);
    1572       13303 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
    1573             : }
    1574             : /* }}} */
    1575             : 
    1576        8189 : ZEND_API int add_next_index_string(zval *arg, const char *str) /* {{{ */
    1577             : {
    1578             :         zval tmp;
    1579             : 
    1580       16378 :         ZVAL_STRING(&tmp, str);
    1581        8189 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
    1582             : }
    1583             : /* }}} */
    1584             : 
    1585      114029 : ZEND_API int add_next_index_stringl(zval *arg, const char *str, size_t length) /* {{{ */
    1586             : {
    1587             :         zval tmp;
    1588             : 
    1589      228058 :         ZVAL_STRINGL(&tmp, str, length);
    1590      114029 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
    1591             : }
    1592             : /* }}} */
    1593             : 
    1594       39228 : ZEND_API int add_next_index_zval(zval *arg, zval *value) /* {{{ */
    1595             : {
    1596       39228 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), value) ? SUCCESS : FAILURE;
    1597             : }
    1598             : /* }}} */
    1599             : 
    1600           0 : ZEND_API zval *add_get_assoc_string_ex(zval *arg, const char *key, uint key_len, const char *str) /* {{{ */
    1601             : {
    1602             :         zval tmp, *ret;
    1603             : 
    1604           0 :         ZVAL_STRING(&tmp, str);
    1605           0 :         ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
    1606           0 :         return ret;
    1607             : }
    1608             : /* }}} */
    1609             : 
    1610           0 : ZEND_API zval *add_get_assoc_stringl_ex(zval *arg, const char *key, uint key_len, const char *str, size_t length) /* {{{ */
    1611             : {
    1612             :         zval tmp, *ret;
    1613             : 
    1614           0 :         ZVAL_STRINGL(&tmp, str, length);
    1615           0 :         ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
    1616           0 :         return ret;
    1617             : }
    1618             : /* }}} */
    1619             : 
    1620           0 : ZEND_API zval *add_get_index_long(zval *arg, zend_ulong index, zend_long l) /* {{{ */
    1621             : {
    1622             :         zval tmp;
    1623             : 
    1624           0 :         ZVAL_LONG(&tmp, l);
    1625           0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
    1626             : }
    1627             : /* }}} */
    1628             : 
    1629           0 : ZEND_API zval *add_get_index_double(zval *arg, zend_ulong index, double d) /* {{{ */
    1630             : {
    1631             :         zval tmp;
    1632             : 
    1633           0 :         ZVAL_DOUBLE(&tmp, d);
    1634           0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
    1635             : }
    1636             : /* }}} */
    1637             : 
    1638           0 : ZEND_API zval *add_get_index_str(zval *arg, zend_ulong index, zend_string *str) /* {{{ */
    1639             : {
    1640             :         zval tmp;
    1641             : 
    1642           0 :         ZVAL_STR(&tmp, str);
    1643           0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
    1644             : }
    1645             : /* }}} */
    1646             : 
    1647           0 : ZEND_API zval *add_get_index_string(zval *arg, zend_ulong index, const char *str) /* {{{ */
    1648             : {
    1649             :         zval tmp;
    1650             : 
    1651           0 :         ZVAL_STRING(&tmp, str);
    1652           0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
    1653             : }
    1654             : /* }}} */
    1655             : 
    1656           0 : ZEND_API zval *add_get_index_stringl(zval *arg, zend_ulong index, const char *str, size_t length) /* {{{ */
    1657             : {
    1658             :         zval tmp;
    1659             : 
    1660           0 :         ZVAL_STRINGL(&tmp, str, length);
    1661           0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
    1662             : }
    1663             : /* }}} */
    1664             : 
    1665        2215 : ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value) /* {{{ */
    1666             : {
    1667             :         zval *result;
    1668             : 
    1669        2215 :         switch (Z_TYPE_P(key)) {
    1670             :                 case IS_STRING:
    1671        4240 :                         result = zend_symtable_update(ht, Z_STR_P(key), value);
    1672        2120 :                         break;
    1673             :                 case IS_NULL:
    1674           2 :                         result = zend_symtable_update(ht, STR_EMPTY_ALLOC(), value);
    1675           1 :                         break;
    1676             :                 case IS_RESOURCE:
    1677           0 :                         zend_error(E_NOTICE, "Resource ID#" ZEND_LONG_FMT " used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(key), Z_RES_HANDLE_P(key));
    1678           0 :                         result = zend_hash_index_update(ht, Z_RES_HANDLE_P(key), value);
    1679           0 :                         break;
    1680             :                 case IS_FALSE:
    1681           0 :                         result = zend_hash_index_update(ht, 0, value);
    1682           0 :                         break;
    1683             :                 case IS_TRUE:
    1684           0 :                         result = zend_hash_index_update(ht, 1, value);
    1685           0 :                         break;
    1686             :                 case IS_LONG:
    1687          91 :                         result = zend_hash_index_update(ht, Z_LVAL_P(key), value);
    1688          91 :                         break;
    1689             :                 case IS_DOUBLE:
    1690           2 :                         result = zend_hash_index_update(ht, zend_dval_to_lval(Z_DVAL_P(key)), value);
    1691           1 :                         break;
    1692             :                 default:
    1693           2 :                         zend_error(E_WARNING, "Illegal offset type");
    1694           2 :                         result = NULL;
    1695             :         }
    1696             : 
    1697        2215 :         if (result) {
    1698        2213 :                 if (Z_REFCOUNTED_P(result)) {
    1699             :                         Z_ADDREF_P(result);
    1700             :                 }
    1701        2213 :                 return SUCCESS;
    1702             :         } else {
    1703           2 :                 return FAILURE;
    1704             :         }
    1705             : }
    1706             : /* }}} */
    1707             : 
    1708        8869 : ZEND_API int add_property_long_ex(zval *arg, const char *key, size_t key_len, zend_long n) /* {{{ */
    1709             : {
    1710             :         zval tmp;
    1711             :         zval z_key;
    1712             : 
    1713        8869 :         ZVAL_LONG(&tmp, n);
    1714       17738 :         ZVAL_STRINGL(&z_key, key, key_len);
    1715        8869 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
    1716        8869 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1717        8869 :         zval_ptr_dtor(&z_key);
    1718        8869 :         return SUCCESS;
    1719             : }
    1720             : /* }}} */
    1721             : 
    1722         349 : ZEND_API int add_property_bool_ex(zval *arg, const char *key, size_t key_len, zend_long b) /* {{{ */
    1723             : {
    1724             :         zval tmp;
    1725             :         zval z_key;
    1726             : 
    1727         349 :         ZVAL_BOOL(&tmp, b);
    1728         698 :         ZVAL_STRINGL(&z_key, key, key_len);
    1729         349 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
    1730         349 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1731         349 :         zval_ptr_dtor(&z_key);
    1732         349 :         return SUCCESS;
    1733             : }
    1734             : /* }}} */
    1735             : 
    1736          95 : ZEND_API int add_property_null_ex(zval *arg, const char *key, size_t key_len) /* {{{ */
    1737             : {
    1738             :         zval tmp;
    1739             :         zval z_key;
    1740             : 
    1741          95 :         ZVAL_NULL(&tmp);
    1742         190 :         ZVAL_STRINGL(&z_key, key, key_len);
    1743          95 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
    1744          95 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1745          95 :         zval_ptr_dtor(&z_key);
    1746          95 :         return SUCCESS;
    1747             : }
    1748             : /* }}} */
    1749             : 
    1750         854 : ZEND_API int add_property_resource_ex(zval *arg, const char *key, size_t key_len, zend_resource *r) /* {{{ */
    1751             : {
    1752             :         zval tmp;
    1753             :         zval z_key;
    1754             : 
    1755         854 :         ZVAL_RES(&tmp, r);
    1756        1708 :         ZVAL_STRINGL(&z_key, key, key_len);
    1757         854 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
    1758         854 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1759         854 :         zval_ptr_dtor(&z_key);
    1760         854 :         return SUCCESS;
    1761             : }
    1762             : /* }}} */
    1763             : 
    1764           0 : ZEND_API int add_property_double_ex(zval *arg, const char *key, size_t key_len, double d) /* {{{ */
    1765             : {
    1766             :         zval tmp;
    1767             :         zval z_key;
    1768             : 
    1769           0 :         ZVAL_DOUBLE(&tmp, d);
    1770           0 :         ZVAL_STRINGL(&z_key, key, key_len);
    1771           0 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
    1772           0 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1773           0 :         zval_ptr_dtor(&z_key);
    1774           0 :         return SUCCESS;
    1775             : }
    1776             : /* }}} */
    1777             : 
    1778        1491 : ZEND_API int add_property_str_ex(zval *arg, const char *key, size_t key_len, zend_string *str) /* {{{ */
    1779             : {
    1780             :         zval tmp;
    1781             :         zval z_key;
    1782             : 
    1783        1491 :         ZVAL_STR(&tmp, str);
    1784        2982 :         ZVAL_STRINGL(&z_key, key, key_len);
    1785        1491 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
    1786        1491 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1787        1491 :         zval_ptr_dtor(&z_key);
    1788        1491 :         return SUCCESS;
    1789             : }
    1790             : /* }}} */
    1791             : 
    1792        2715 : ZEND_API int add_property_string_ex(zval *arg, const char *key, size_t key_len, const char *str) /* {{{ */
    1793             : {
    1794             :         zval tmp;
    1795             :         zval z_key;
    1796             : 
    1797        5430 :         ZVAL_STRING(&tmp, str);
    1798        5430 :         ZVAL_STRINGL(&z_key, key, key_len);
    1799        2715 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
    1800        2715 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1801        2715 :         zval_ptr_dtor(&z_key);
    1802        2715 :         return SUCCESS;
    1803             : }
    1804             : /* }}} */
    1805             : 
    1806        6806 : ZEND_API int add_property_stringl_ex(zval *arg, const char *key, size_t key_len, const char *str, size_t length) /* {{{ */
    1807             : {
    1808             :         zval tmp;
    1809             :         zval z_key;
    1810             : 
    1811       13612 :         ZVAL_STRINGL(&tmp, str, length);
    1812       13612 :         ZVAL_STRINGL(&z_key, key, key_len);
    1813        6806 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
    1814        6806 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1815        6806 :         zval_ptr_dtor(&z_key);
    1816        6806 :         return SUCCESS;
    1817             : }
    1818             : /* }}} */
    1819             : 
    1820        1934 : ZEND_API int add_property_zval_ex(zval *arg, const char *key, size_t key_len, zval *value) /* {{{ */
    1821             : {
    1822             :         zval z_key;
    1823             : 
    1824        3868 :         ZVAL_STRINGL(&z_key, key, key_len);
    1825        1934 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, value, NULL);
    1826        1934 :         zval_ptr_dtor(&z_key);
    1827        1934 :         return SUCCESS;
    1828             : }
    1829             : /* }}} */
    1830             : 
    1831     1443447 : ZEND_API int zend_startup_module_ex(zend_module_entry *module) /* {{{ */
    1832             : {
    1833             :         size_t name_len;
    1834             :         zend_string *lcname;
    1835             : 
    1836     1443447 :         if (module->module_started) {
    1837           0 :                 return SUCCESS;
    1838             :         }
    1839     1443447 :         module->module_started = 1;
    1840             : 
    1841             :         /* Check module dependencies */
    1842     1443447 :         if (module->deps) {
    1843      418320 :                 const zend_module_dep *dep = module->deps;
    1844             : 
    1845     1485036 :                 while (dep->name) {
    1846      648396 :                         if (dep->type == MODULE_DEP_REQUIRED) {
    1847             :                                 zend_module_entry *req_mod;
    1848             : 
    1849      460152 :                                 name_len = strlen(dep->name);
    1850      460152 :                                 lcname = zend_string_alloc(name_len, 0);
    1851      460152 :                                 zend_str_tolower_copy(lcname->val, dep->name, name_len);
    1852             : 
    1853      460152 :                                 if ((req_mod = zend_hash_find_ptr(&module_registry, lcname)) == NULL || !req_mod->module_started) {
    1854             :                                         zend_string_free(lcname);
    1855             :                                         /* TODO: Check version relationship */
    1856           0 :                                         zend_error(E_CORE_WARNING, "Cannot load module '%s' because required module '%s' is not loaded", module->name, dep->name);
    1857           0 :                                         module->module_started = 0;
    1858           0 :                                         return FAILURE;
    1859             :                                 }
    1860             :                                 zend_string_free(lcname);
    1861             :                         }
    1862      648396 :                         ++dep;
    1863             :                 }
    1864             :         }
    1865             : 
    1866             :         /* Initialize module globals */
    1867     1443447 :         if (module->globals_size) {
    1868             : #ifdef ZTS
    1869             :                 ts_allocate_id(module->globals_id_ptr, module->globals_size, (ts_allocate_ctor) module->globals_ctor, (ts_allocate_dtor) module->globals_dtor);
    1870             : #else
    1871      669312 :                 if (module->globals_ctor) {
    1872      627480 :                         module->globals_ctor(module->globals_ptr);
    1873             :                 }
    1874             : #endif
    1875             :         }
    1876     1443447 :         if (module->module_startup_func) {
    1877     1380699 :                 EG(current_module) = module;
    1878     1380699 :                 if (module->module_startup_func(module->type, module->module_number)==FAILURE) {
    1879           0 :                         zend_error_noreturn(E_CORE_ERROR,"Unable to start %s module", module->name);
    1880             :                         EG(current_module) = NULL;
    1881             :                         return FAILURE;
    1882             :                 }
    1883     1380699 :                 EG(current_module) = NULL;
    1884             :         }
    1885     1443447 :         return SUCCESS;
    1886             : }
    1887             : /* }}} */
    1888             : 
    1889     1422694 : static int zend_startup_module_zval(zval *zv) /* {{{ */
    1890             : {
    1891     1422694 :         zend_module_entry *module = Z_PTR_P(zv);
    1892             : 
    1893     1422694 :         return zend_startup_module_ex(module);
    1894             : }
    1895             : /* }}} */
    1896             : 
    1897       20916 : static void zend_sort_modules(void *base, size_t count, size_t siz, compare_func_t compare, swap_func_t swp) /* {{{ */
    1898             : {
    1899       20916 :         Bucket *b1 = base;
    1900             :         Bucket *b2;
    1901       20916 :         Bucket *end = b1 + count;
    1902             :         Bucket tmp;
    1903             :         zend_module_entry *m, *r;
    1904             : 
    1905     1443610 :         while (b1 < end) {
    1906             : try_again:
    1907     1569106 :                 m = (zend_module_entry*)Z_PTR(b1->val);
    1908     1569106 :                 if (!m->module_started && m->deps) {
    1909      585648 :                         const zend_module_dep *dep = m->deps;
    1910     1861524 :                         while (dep->name) {
    1911      857556 :                                 if (dep->type == MODULE_DEP_REQUIRED || dep->type == MODULE_DEP_OPTIONAL) {
    1912      836640 :                                         b2 = b1 + 1;
    1913    21263648 :                                         while (b2 < end) {
    1914    19757696 :                                                 r = (zend_module_entry*)Z_PTR(b2->val);
    1915    19757696 :                                                 if (strcasecmp(dep->name, r->name) == 0) {
    1916      167328 :                                                         tmp = *b1;
    1917      167328 :                                                         *b1 = *b2;
    1918      167328 :                                                         *b2 = tmp;
    1919      167328 :                                                         goto try_again;
    1920             :                                                 }
    1921    19590368 :                                                 b2++;
    1922             :                                         }
    1923             :                                 }
    1924      690228 :                                 dep++;
    1925             :                         }
    1926             :                 }
    1927     1401778 :                 b1++;
    1928             :         }
    1929       20916 : }
    1930             : /* }}} */
    1931             : 
    1932       20916 : ZEND_API void zend_collect_module_handlers(void) /* {{{ */
    1933             : {
    1934             :         zend_module_entry *module;
    1935       20916 :         int startup_count = 0;
    1936       20916 :         int shutdown_count = 0;
    1937       20916 :         int post_deactivate_count = 0;
    1938             :         zend_class_entry *ce;
    1939       20916 :         int class_count = 0;
    1940             : 
    1941             :         /* Collect extensions with request startup/shutdown handlers */
    1942     2907810 :         ZEND_HASH_FOREACH_PTR(&module_registry, module) {
    1943     1443447 :                 if (module->request_startup_func) {
    1944      313740 :                         startup_count++;
    1945             :                 }
    1946     1443447 :                 if (module->request_shutdown_func) {
    1947      418320 :                         shutdown_count++;
    1948             :                 }
    1949     1443447 :                 if (module->post_deactivate_func) {
    1950       20916 :                         post_deactivate_count++;
    1951             :                 }
    1952             :         } ZEND_HASH_FOREACH_END();
    1953       20916 :         module_request_startup_handlers = (zend_module_entry**)malloc(
    1954             :             sizeof(zend_module_entry*) *
    1955       41832 :                 (startup_count + 1 +
    1956       20916 :                  shutdown_count + 1 +
    1957       20916 :                  post_deactivate_count + 1));
    1958       20916 :         module_request_startup_handlers[startup_count] = NULL;
    1959       20916 :         module_request_shutdown_handlers = module_request_startup_handlers + startup_count + 1;
    1960       20916 :         module_request_shutdown_handlers[shutdown_count] = NULL;
    1961       20916 :         module_post_deactivate_handlers = module_request_shutdown_handlers + shutdown_count + 1;
    1962       20916 :         module_post_deactivate_handlers[post_deactivate_count] = NULL;
    1963       20916 :         startup_count = 0;
    1964             : 
    1965     2907810 :         ZEND_HASH_FOREACH_PTR(&module_registry, module) {
    1966     1443447 :                 if (module->request_startup_func) {
    1967      313740 :                         module_request_startup_handlers[startup_count++] = module;
    1968             :                 }
    1969     1443447 :                 if (module->request_shutdown_func) {
    1970      418320 :                         module_request_shutdown_handlers[--shutdown_count] = module;
    1971             :                 }
    1972     1443447 :                 if (module->post_deactivate_func) {
    1973       20916 :                         module_post_deactivate_handlers[--post_deactivate_count] = module;
    1974             :                 }
    1975             :         } ZEND_HASH_FOREACH_END();
    1976             : 
    1977             :         /* Collect internal classes with static members */
    1978     7843500 :         ZEND_HASH_FOREACH_PTR(CG(class_table), ce) {
    1979     7822584 :                 if (ce->type == ZEND_INTERNAL_CLASS &&
    1980     3911292 :                     ce->default_static_members_count > 0) {
    1981           0 :                     class_count++;
    1982             :                 }
    1983             :         } ZEND_HASH_FOREACH_END();
    1984             : 
    1985       20916 :         class_cleanup_handlers = (zend_class_entry**)malloc(
    1986             :                 sizeof(zend_class_entry*) *
    1987       20916 :                 (class_count + 1));
    1988       20916 :         class_cleanup_handlers[class_count] = NULL;
    1989             : 
    1990       20916 :         if (class_count) {
    1991           0 :                 ZEND_HASH_FOREACH_PTR(CG(class_table), ce) {
    1992           0 :                         if (ce->type == ZEND_INTERNAL_CLASS &&
    1993           0 :                             ce->default_static_members_count > 0) {
    1994           0 :                             class_cleanup_handlers[--class_count] = ce;
    1995             :                         }
    1996             :                 } ZEND_HASH_FOREACH_END();
    1997             :         }
    1998       20916 : }
    1999             : /* }}} */
    2000             : 
    2001       20916 : ZEND_API int zend_startup_modules(void) /* {{{ */
    2002             : {
    2003       20916 :         zend_hash_sort_ex(&module_registry, zend_sort_modules, NULL, 0);
    2004       20916 :         zend_hash_apply(&module_registry, zend_startup_module_zval);
    2005       20916 :         return SUCCESS;
    2006             : }
    2007             : /* }}} */
    2008             : 
    2009       20952 : ZEND_API void zend_destroy_modules(void) /* {{{ */
    2010             : {
    2011       20952 :         free(class_cleanup_handlers);
    2012       20952 :         free(module_request_startup_handlers);
    2013       20952 :         zend_hash_graceful_reverse_destroy(&module_registry);
    2014       20952 : }
    2015             : /* }}} */
    2016             : 
    2017     1443447 : ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module) /* {{{ */
    2018             : {
    2019             :         size_t name_len;
    2020             :         zend_string *lcname;
    2021             :         zend_module_entry *module_ptr;
    2022             : 
    2023     1443447 :         if (!module) {
    2024           0 :                 return NULL;
    2025             :         }
    2026             : 
    2027             : #if 0
    2028             :         zend_printf("%s: Registering module %d\n", module->name, module->module_number);
    2029             : #endif
    2030             : 
    2031             :         /* Check module dependencies */
    2032     1443447 :         if (module->deps) {
    2033      418320 :                 const zend_module_dep *dep = module->deps;
    2034             : 
    2035     1485036 :                 while (dep->name) {
    2036      648396 :                         if (dep->type == MODULE_DEP_CONFLICTS) {
    2037       20916 :                                 name_len = strlen(dep->name);
    2038       20916 :                                 lcname = zend_string_alloc(name_len, 0);
    2039       20916 :                                 zend_str_tolower_copy(lcname->val, dep->name, name_len);
    2040             : 
    2041       20916 :                                 if (zend_hash_exists(&module_registry, lcname)) {
    2042             :                                         zend_string_free(lcname);
    2043             :                                         /* TODO: Check version relationship */
    2044           0 :                                         zend_error(E_CORE_WARNING, "Cannot load module '%s' because conflicting module '%s' is already loaded", module->name, dep->name);
    2045           0 :                                         return NULL;
    2046             :                                 }
    2047             :                                 zend_string_free(lcname);
    2048             :                         }
    2049      648396 :                         ++dep;
    2050             :                 }
    2051             :         }
    2052             : 
    2053     1443447 :         name_len = strlen(module->name);
    2054     1443447 :         lcname = zend_string_alloc(name_len, 1);
    2055     1443447 :         zend_str_tolower_copy(lcname->val, module->name, name_len);
    2056             : 
    2057     1443447 :         if ((module_ptr = zend_hash_add_mem(&module_registry, lcname, module, sizeof(zend_module_entry))) == NULL) {
    2058           0 :                 zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name);
    2059             :                 zend_string_release(lcname);
    2060           0 :                 return NULL;
    2061             :         }
    2062             :         zend_string_release(lcname);
    2063     1443447 :         module = module_ptr;
    2064     1443447 :         EG(current_module) = module;
    2065             : 
    2066     1443447 :         if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type)==FAILURE) {
    2067           0 :                 EG(current_module) = NULL;
    2068           0 :                 zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name);
    2069           0 :                 return NULL;
    2070             :         }
    2071             : 
    2072     1443447 :         EG(current_module) = NULL;
    2073     1443447 :         return module;
    2074             : }
    2075             : /* }}} */
    2076             : 
    2077     1422531 : ZEND_API zend_module_entry* zend_register_internal_module(zend_module_entry *module) /* {{{ */
    2078             : {
    2079     1422531 :         module->module_number = zend_next_free_module();
    2080     1422531 :         module->type = MODULE_PERSISTENT;
    2081     1422531 :         return zend_register_module_ex(module);
    2082             : }
    2083             : /* }}} */
    2084             : 
    2085     2443722 : ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, int error_type) /* {{{ */
    2086             : {
    2087             :         char lcname[16];
    2088             :         size_t name_len;
    2089             : 
    2090             :         /* we don't care if the function name is longer, in fact lowercasing only
    2091             :          * the beginning of the name speeds up the check process */
    2092     2443722 :         name_len = fptr->common.function_name->len;
    2093     2443722 :         zend_str_tolower_copy(lcname, fptr->common.function_name->val, MIN(name_len, sizeof(lcname)-1));
    2094     2443722 :         lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */
    2095             : 
    2096     2443722 :         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) {
    2097           1 :                 zend_error(error_type, "Destructor %s::%s() cannot take arguments", ce->name->val, ZEND_DESTRUCTOR_FUNC_NAME);
    2098     2443721 :         } 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) {
    2099           1 :                 zend_error(error_type, "Method %s::%s() cannot accept any arguments", ce->name->val, ZEND_CLONE_FUNC_NAME);
    2100     2443783 :         } else if (name_len == sizeof(ZEND_GET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME) - 1)) {
    2101          65 :                 if (fptr->common.num_args != 1) {
    2102           1 :                         zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name->val, ZEND_GET_FUNC_NAME);
    2103          64 :                 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
    2104           1 :                         zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name->val, ZEND_GET_FUNC_NAME);
    2105             :                 }
    2106     2443713 :         } else if (name_len == sizeof(ZEND_SET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME) - 1)) {
    2107          62 :                 if (fptr->common.num_args != 2) {
    2108           2 :                         zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name->val, ZEND_SET_FUNC_NAME);
    2109         119 :                 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
    2110           2 :                         zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name->val, ZEND_SET_FUNC_NAME);
    2111             :                 }
    2112     2443608 :         } else if (name_len == sizeof(ZEND_UNSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME) - 1)) {
    2113          17 :                 if (fptr->common.num_args != 1) {
    2114           1 :                         zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name->val, ZEND_UNSET_FUNC_NAME);
    2115          16 :                 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
    2116           1 :                         zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name->val, ZEND_UNSET_FUNC_NAME);
    2117             :                 }
    2118     2443590 :         } else if (name_len == sizeof(ZEND_ISSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME) - 1)) {
    2119          16 :                 if (fptr->common.num_args != 1) {
    2120           1 :                         zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name->val, ZEND_ISSET_FUNC_NAME);
    2121          15 :                 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
    2122           1 :                         zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name->val, ZEND_ISSET_FUNC_NAME);
    2123             :                 }
    2124     2464539 :         } else if (name_len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME) - 1)) {
    2125       20982 :                 if (fptr->common.num_args != 2) {
    2126           1 :                         zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name->val, ZEND_CALL_FUNC_NAME);
    2127       41961 :                 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
    2128           2 :                         zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name->val, ZEND_CALL_FUNC_NAME);
    2129             :                 }
    2130     2423863 :         } else if (name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME) - 1 &&
    2131        1254 :                 !memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1)
    2132             :         ) {
    2133          31 :                 if (fptr->common.num_args != 2) {
    2134           0 :                         zend_error(error_type, "Method %s::__callStatic() must take exactly 2 arguments", ce->name->val);
    2135          62 :                 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
    2136           0 :                         zend_error(error_type, "Method %s::__callStatic() cannot take arguments by reference", ce->name->val);
    2137             :                 }
    2138     3179065 :         } else if (name_len == sizeof(ZEND_TOSTRING_FUNC_NAME) - 1 &&
    2139      756518 :                 !memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && fptr->common.num_args != 0
    2140             :         ) {
    2141           1 :                 zend_error(error_type, "Method %s::%s() cannot take arguments", ce->name->val, ZEND_TOSTRING_FUNC_NAME);
    2142     4140530 :         } else if (name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME) - 1 &&
    2143     1717984 :                 !memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && fptr->common.num_args != 0) {
    2144           0 :                 zend_error(error_type, "Method %s::%s() cannot take arguments", ce->name->val, ZEND_DEBUGINFO_FUNC_NAME);
    2145             :         }
    2146     2443706 : }
    2147             : /* }}} */
    2148             : 
    2149             : /* registers all functions in *library_functions in the function hash */
    2150     4706128 : ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_function_entry *functions, HashTable *function_table, int type) /* {{{ */
    2151             : {
    2152     4706128 :         const zend_function_entry *ptr = functions;
    2153             :         zend_function function, *reg_function;
    2154     4706128 :         zend_internal_function *internal_function = (zend_internal_function *)&function;
    2155     4706128 :         int count=0, unload=0;
    2156     4706128 :         HashTable *target_function_table = function_table;
    2157             :         int error_type;
    2158     4706128 :         zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL, *__debugInfo = NULL;
    2159             :         zend_string *lowercase_name;
    2160             :         size_t fname_len;
    2161     4706128 :         const char *lc_class_name = NULL;
    2162     4706128 :         size_t class_name_len = 0;
    2163             : 
    2164     4706128 :         if (type==MODULE_PERSISTENT) {
    2165     4706128 :                 error_type = E_CORE_WARNING;
    2166             :         } else {
    2167           0 :                 error_type = E_WARNING;
    2168             :         }
    2169             : 
    2170     4706128 :         if (!target_function_table) {
    2171     1401400 :                 target_function_table = CG(function_table);
    2172             :         }
    2173     4706128 :         internal_function->type = ZEND_INTERNAL_FUNCTION;
    2174     4706128 :         internal_function->module = EG(current_module);
    2175             : 
    2176     4706128 :         if (scope) {
    2177     3304728 :                 class_name_len = scope->name->len;
    2178     6609456 :                 if ((lc_class_name = zend_memrchr(scope->name->val, '\\', class_name_len))) {
    2179           0 :                         ++lc_class_name;
    2180           0 :                         class_name_len -= (lc_class_name - scope->name->val);
    2181           0 :                         lc_class_name = zend_str_tolower_dup(lc_class_name, class_name_len);
    2182             :                 } else {
    2183     3304728 :                         lc_class_name = zend_str_tolower_dup(scope->name->val, class_name_len);
    2184             :                 }
    2185             :         }
    2186             : 
    2187    85483367 :         while (ptr->fname) {
    2188    76071111 :                 fname_len = strlen(ptr->fname);
    2189    76071111 :                 internal_function->handler = ptr->handler;
    2190   152142222 :                 internal_function->function_name = zend_new_interned_string(zend_string_init(ptr->fname, fname_len, 1));
    2191    76071111 :                 internal_function->scope = scope;
    2192    76071111 :                 internal_function->prototype = NULL;
    2193    76071111 :                 if (ptr->flags) {
    2194    20978748 :                         if (!(ptr->flags & ZEND_ACC_PPP_MASK)) {
    2195           0 :                                 if (ptr->flags != ZEND_ACC_DEPRECATED || scope) {
    2196           0 :                                         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);
    2197             :                                 }
    2198           0 :                                 internal_function->fn_flags = ZEND_ACC_PUBLIC | ptr->flags;
    2199             :                         } else {
    2200    20978748 :                                 internal_function->fn_flags = ptr->flags;
    2201             :                         }
    2202             :                 } else {
    2203    55092363 :                         internal_function->fn_flags = ZEND_ACC_PUBLIC;
    2204             :                 }
    2205    76071111 :                 if (ptr->arg_info) {
    2206    74481495 :                         zend_internal_function_info *info = (zend_internal_function_info*)ptr->arg_info;
    2207             : 
    2208    74481495 :                         internal_function->arg_info = (zend_internal_arg_info*)ptr->arg_info+1;
    2209    74481495 :                         internal_function->num_args = ptr->num_args;
    2210             :                         /* Currently you cannot denote that the function can accept less arguments than num_args */
    2211    74481495 :                         if (info->required_num_args == (zend_uintptr_t)-1) {
    2212    27525727 :                                 internal_function->required_num_args = ptr->num_args;
    2213             :                         } else {
    2214    46955768 :                                 internal_function->required_num_args = info->required_num_args;
    2215             :                         }
    2216    74481495 :                         if (info->return_reference) {
    2217           0 :                                 internal_function->fn_flags |= ZEND_ACC_RETURN_REFERENCE;
    2218             :                         }
    2219    74481495 :                         if (ptr->arg_info[ptr->num_args].is_variadic) {
    2220      857556 :                                 internal_function->fn_flags |= ZEND_ACC_VARIADIC;
    2221             :                                 /* Don't count the variadic argument */
    2222      857556 :                                 internal_function->num_args--;
    2223             :                         }
    2224    74481495 :                         if (info->type_hint) {
    2225           0 :                                 if (info->class_name) {
    2226             :                                         ZEND_ASSERT(info->type_hint == IS_OBJECT);
    2227           0 :                                         if (!scope && (!strcasecmp(info->class_name, "self") || !strcasecmp(info->class_name, "parent"))) {
    2228           0 :                                                 zend_error_noreturn(E_CORE_ERROR, "Cannot declare a return type of %s outside of a class scope", info->class_name);
    2229             :                                         }
    2230             :                                 }
    2231             : 
    2232           0 :                                 internal_function->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE;
    2233             :                         }
    2234             :                 } else {
    2235     1589616 :                         internal_function->arg_info = NULL;
    2236     1589616 :                         internal_function->num_args = 0;
    2237     1589616 :                         internal_function->required_num_args = 0;
    2238             :                 }
    2239    76071111 :                 zend_set_function_arg_flags((zend_function*)internal_function);
    2240    76071111 :                 if (ptr->flags & ZEND_ACC_ABSTRACT) {
    2241      857556 :                         if (scope) {
    2242             :                                 /* This is a class that must be abstract itself. Here we set the check info. */
    2243      857556 :                                 scope->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    2244      857556 :                                 if (!(scope->ce_flags & ZEND_ACC_INTERFACE)) {
    2245             :                                         /* Since the class is not an interface it needs to be declared as a abstract class. */
    2246             :                                         /* Since here we are handling internal functions only we can add the keyword flag. */
    2247             :                                         /* This time we set the flag for the keyword 'abstract'. */
    2248      230076 :                                         scope->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
    2249             :                                 }
    2250             :                         }
    2251      857556 :                         if (ptr->flags & ZEND_ACC_STATIC && (!scope || !(scope->ce_flags & ZEND_ACC_INTERFACE))) {
    2252           0 :                                 zend_error(error_type, "Static function %s%s%s() cannot be abstract", scope ? scope->name->val : "", scope ? "::" : "", ptr->fname);
    2253             :                         }
    2254             :                 } else {
    2255    75213555 :                         if (scope && (scope->ce_flags & ZEND_ACC_INTERFACE)) {
    2256           0 :                                 efree((char*)lc_class_name);
    2257           0 :                                 zend_error(error_type, "Interface %s cannot contain non abstract method %s()", scope->name->val, ptr->fname);
    2258           0 :                                 return FAILURE;
    2259             :                         }
    2260    75213555 :                         if (!internal_function->handler) {
    2261           0 :                                 if (scope) {
    2262           0 :                                         efree((char*)lc_class_name);
    2263             :                                 }
    2264           0 :                                 zend_error(error_type, "Method %s%s%s() cannot be a NULL function", scope ? scope->name->val : "", scope ? "::" : "", ptr->fname);
    2265           0 :                                 zend_unregister_functions(functions, count, target_function_table);
    2266           0 :                                 return FAILURE;
    2267             :                         }
    2268             :                 }
    2269    76071111 :                 lowercase_name = zend_string_alloc(fname_len, 1);
    2270    76071111 :                 zend_str_tolower_copy(lowercase_name->val, ptr->fname, fname_len);
    2271    76071111 :                 lowercase_name = zend_new_interned_string(lowercase_name);
    2272    76071111 :                 reg_function = malloc(sizeof(zend_internal_function));
    2273    76071111 :                 memcpy(reg_function, &function, sizeof(zend_internal_function));
    2274    76071111 :                 if (zend_hash_add_ptr(target_function_table, lowercase_name, reg_function) == NULL) {
    2275           0 :                         unload=1;
    2276           0 :                         free(reg_function);
    2277             :                         zend_string_release(lowercase_name);
    2278           0 :                         break;
    2279             :                 }
    2280             : 
    2281             :                 /* If types of arguments have to be checked */
    2282    76071111 :                 if (reg_function->common.arg_info && reg_function->common.num_args) {
    2283             :                         uint32_t i;
    2284   168601167 :                         for (i = 0; i < reg_function->common.num_args; i++) {
    2285   227521376 :                                 if (reg_function->common.arg_info[i].class_name ||
    2286   112505728 :                                     reg_function->common.arg_info[i].type_hint) {
    2287     2844576 :                                     reg_function->common.fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
    2288     2844576 :                                         break;
    2289             :                                 }
    2290             :                         }
    2291             :                 }
    2292             : 
    2293    76071111 :                 if (scope) {
    2294             :                         /* Look for ctor, dtor, clone
    2295             :                          * If it's an old-style constructor, store it only if we don't have
    2296             :                          * a constructor already.
    2297             :                          */
    2298    32900868 :                         if ((fname_len == class_name_len) && !ctor && !memcmp(lowercase_name->val, lc_class_name, class_name_len+1)) {
    2299      167328 :                                 ctor = reg_function;
    2300    34281324 :                         } else if (zend_string_equals_literal(lowercase_name, ZEND_CONSTRUCTOR_FUNC_NAME)) {
    2301     1715112 :                                 ctor = reg_function;
    2302    30913848 :                         } else if (zend_string_equals_literal(lowercase_name, ZEND_DESTRUCTOR_FUNC_NAME)) {
    2303       62748 :                                 dtor = reg_function;
    2304       62748 :                                 if (internal_function->num_args) {
    2305           0 :                                         zend_error(error_type, "Destructor %s::%s() cannot take arguments", scope->name->val, ptr->fname);
    2306             :                                 }
    2307    30934764 :                         } else if (zend_string_equals_literal(lowercase_name, ZEND_CLONE_FUNC_NAME)) {
    2308      146412 :                                 clone = reg_function;
    2309    30662856 :                         } else if (zend_string_equals_literal(lowercase_name, ZEND_CALL_FUNC_NAME)) {
    2310       20916 :                                 __call = reg_function;
    2311    30621024 :                         } else if (zend_string_equals_literal(lowercase_name, ZEND_CALLSTATIC_FUNC_NAME)) {
    2312           0 :                                 __callstatic = reg_function;
    2313    30934764 :                         } else if (zend_string_equals_literal(lowercase_name, ZEND_TOSTRING_FUNC_NAME)) {
    2314      313740 :                                 __tostring = reg_function;
    2315    30307284 :                         } else if (zend_string_equals_literal(lowercase_name, ZEND_GET_FUNC_NAME)) {
    2316           0 :                                 __get = reg_function;
    2317           0 :                                 scope->ce_flags |= ZEND_ACC_USE_GUARDS;
    2318    30307284 :                         } else if (zend_string_equals_literal(lowercase_name, ZEND_SET_FUNC_NAME)) {
    2319           0 :                                 __set = reg_function;
    2320           0 :                                 scope->ce_flags |= ZEND_ACC_USE_GUARDS;
    2321    30307284 :                         } else if (zend_string_equals_literal(lowercase_name, ZEND_UNSET_FUNC_NAME)) {
    2322           0 :                                 __unset = reg_function;
    2323           0 :                                 scope->ce_flags |= ZEND_ACC_USE_GUARDS;
    2324    30307284 :                         } else if (zend_string_equals_literal(lowercase_name, ZEND_ISSET_FUNC_NAME)) {
    2325           0 :                                 __isset = reg_function;
    2326           0 :                                 scope->ce_flags |= ZEND_ACC_USE_GUARDS;
    2327    30307284 :                         } else if (zend_string_equals_literal(lowercase_name, ZEND_DEBUGINFO_FUNC_NAME)) {
    2328           0 :                                 __debugInfo = reg_function;
    2329             :                         } else {
    2330    30307284 :                                 reg_function = NULL;
    2331             :                         }
    2332    32733540 :                         if (reg_function) {
    2333     2426256 :                                 zend_check_magic_method_implementation(scope, reg_function, error_type);
    2334             :                         }
    2335             :                 }
    2336    76071111 :                 ptr++;
    2337    76071111 :                 count++;
    2338             :                 zend_string_release(lowercase_name);
    2339             :         }
    2340     4706128 :         if (unload) { /* before unloading, display all remaining bad function in the module */
    2341           0 :                 if (scope) {
    2342           0 :                         efree((char*)lc_class_name);
    2343             :                 }
    2344           0 :                 while (ptr->fname) {
    2345           0 :                         fname_len = strlen(ptr->fname);
    2346           0 :                         lowercase_name = zend_string_alloc(fname_len, 0);
    2347           0 :                         zend_str_tolower_copy(lowercase_name->val, ptr->fname, fname_len);
    2348           0 :                         if (zend_hash_exists(target_function_table, lowercase_name)) {
    2349           0 :                                 zend_error(error_type, "Function registration failed - duplicate name - %s%s%s", scope ? scope->name->val : "", scope ? "::" : "", ptr->fname);
    2350             :                         }
    2351             :                         zend_string_free(lowercase_name);
    2352           0 :                         ptr++;
    2353             :                 }
    2354           0 :                 zend_unregister_functions(functions, count, target_function_table);
    2355           0 :                 return FAILURE;
    2356             :         }
    2357     4706128 :         if (scope) {
    2358     3304728 :                 scope->constructor = ctor;
    2359     3304728 :                 scope->destructor = dtor;
    2360     3304728 :                 scope->clone = clone;
    2361     3304728 :                 scope->__call = __call;
    2362     3304728 :                 scope->__callstatic = __callstatic;
    2363     3304728 :                 scope->__tostring = __tostring;
    2364     3304728 :                 scope->__get = __get;
    2365     3304728 :                 scope->__set = __set;
    2366     3304728 :                 scope->__unset = __unset;
    2367     3304728 :                 scope->__isset = __isset;
    2368     3304728 :                 scope->__debugInfo = __debugInfo;
    2369     3304728 :                 if (ctor) {
    2370     1882440 :                         ctor->common.fn_flags |= ZEND_ACC_CTOR;
    2371     1882440 :                         if (ctor->common.fn_flags & ZEND_ACC_STATIC) {
    2372           0 :                                 zend_error(error_type, "Constructor %s::%s() cannot be static", scope->name->val, ctor->common.function_name->val);
    2373             :                         }
    2374     1882440 :                         ctor->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    2375             :                 }
    2376     3304728 :                 if (dtor) {
    2377       62748 :                         dtor->common.fn_flags |= ZEND_ACC_DTOR;
    2378       62748 :                         if (dtor->common.fn_flags & ZEND_ACC_STATIC) {
    2379           0 :                                 zend_error(error_type, "Destructor %s::%s() cannot be static", scope->name->val, dtor->common.function_name->val);
    2380             :                         }
    2381       62748 :                         dtor->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    2382             :                 }
    2383     3304728 :                 if (clone) {
    2384      146412 :                         clone->common.fn_flags |= ZEND_ACC_CLONE;
    2385      146412 :                         if (clone->common.fn_flags & ZEND_ACC_STATIC) {
    2386           0 :                                 zend_error(error_type, "Constructor %s::%s() cannot be static", scope->name->val, clone->common.function_name->val);
    2387             :                         }
    2388      146412 :                         clone->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    2389             :                 }
    2390     3304728 :                 if (__call) {
    2391       20916 :                         if (__call->common.fn_flags & ZEND_ACC_STATIC) {
    2392           0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name->val, __call->common.function_name->val);
    2393             :                         }
    2394       20916 :                         __call->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    2395             :                 }
    2396     3304728 :                 if (__callstatic) {
    2397           0 :                         if (!(__callstatic->common.fn_flags & ZEND_ACC_STATIC)) {
    2398           0 :                                 zend_error(error_type, "Method %s::%s() must be static", scope->name->val, __callstatic->common.function_name->val);
    2399             :                         }
    2400           0 :                         __callstatic->common.fn_flags |= ZEND_ACC_STATIC;
    2401             :                 }
    2402     3304728 :                 if (__tostring) {
    2403      313740 :                         if (__tostring->common.fn_flags & ZEND_ACC_STATIC) {
    2404           0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name->val, __tostring->common.function_name->val);
    2405             :                         }
    2406      313740 :                         __tostring->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    2407             :                 }
    2408     3304728 :                 if (__get) {
    2409           0 :                         if (__get->common.fn_flags & ZEND_ACC_STATIC) {
    2410           0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name->val, __get->common.function_name->val);
    2411             :                         }
    2412           0 :                         __get->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    2413             :                 }
    2414     3304728 :                 if (__set) {
    2415           0 :                         if (__set->common.fn_flags & ZEND_ACC_STATIC) {
    2416           0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name->val, __set->common.function_name->val);
    2417             :                         }
    2418           0 :                         __set->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    2419             :                 }
    2420     3304728 :                 if (__unset) {
    2421           0 :                         if (__unset->common.fn_flags & ZEND_ACC_STATIC) {
    2422           0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name->val, __unset->common.function_name->val);
    2423             :                         }
    2424           0 :                         __unset->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    2425             :                 }
    2426     3304728 :                 if (__isset) {
    2427           0 :                         if (__isset->common.fn_flags & ZEND_ACC_STATIC) {
    2428           0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name->val, __isset->common.function_name->val);
    2429             :                         }
    2430           0 :                         __isset->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    2431             :                 }
    2432     3304728 :                 if (__debugInfo) {
    2433           0 :                         if (__debugInfo->common.fn_flags & ZEND_ACC_STATIC) {
    2434           0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name->val, __debugInfo->common.function_name->val);
    2435             :                         }
    2436             :                 }
    2437             : 
    2438     3304728 :                 if (ctor && ctor->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && ctor->common.fn_flags & ZEND_ACC_CTOR) {
    2439           0 :                         zend_error_noreturn(E_CORE_ERROR, "Constructor %s::%s() cannot declare a return type", scope->name->val, ctor->common.function_name->val);
    2440             :                 }
    2441             : 
    2442     3304728 :                 if (dtor && dtor->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && dtor->common.fn_flags & ZEND_ACC_DTOR) {
    2443           0 :                         zend_error_noreturn(E_CORE_ERROR, "Destructor %s::%s() cannot declare a return type", scope->name->val, dtor->common.function_name->val);
    2444             :                 }
    2445             : 
    2446     3304728 :                 if (clone && clone->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && dtor->common.fn_flags & ZEND_ACC_DTOR) {
    2447           0 :                         zend_error_noreturn(E_CORE_ERROR, "%s::%s() cannot declare a return type", scope->name->val, clone->common.function_name->val);
    2448             :                 }
    2449     3304728 :                 efree((char*)lc_class_name);
    2450             :         }
    2451     4706128 :         return SUCCESS;
    2452             : }
    2453             : /* }}} */
    2454             : 
    2455             : /* count=-1 means erase all functions, otherwise,
    2456             :  * erase the first count functions
    2457             :  */
    2458     1383075 : ZEND_API void zend_unregister_functions(const zend_function_entry *functions, int count, HashTable *function_table) /* {{{ */
    2459             : {
    2460     1383075 :         const zend_function_entry *ptr = functions;
    2461     1383075 :         int i=0;
    2462     1383075 :         HashTable *target_function_table = function_table;
    2463             :         zend_string *lowercase_name;
    2464             :         size_t fname_len;
    2465             : 
    2466     1383075 :         if (!target_function_table) {
    2467     1383075 :                 target_function_table = CG(function_table);
    2468             :         }
    2469    46116490 :         while (ptr->fname) {
    2470    43350340 :                 if (count!=-1 && i>=count) {
    2471           0 :                         break;
    2472             :                 }
    2473    43350340 :                 fname_len = strlen(ptr->fname);
    2474    43350340 :                 lowercase_name = zend_string_alloc(fname_len, 0);
    2475    43350340 :                 zend_str_tolower_copy(lowercase_name->val, ptr->fname, fname_len);
    2476    43350340 :                 zend_hash_del(target_function_table, lowercase_name);
    2477             :                 zend_string_free(lowercase_name);
    2478    43350340 :                 ptr++;
    2479    43350340 :                 i++;
    2480             :         }
    2481     1383075 : }
    2482             : /* }}} */
    2483             : 
    2484       20753 : ZEND_API int zend_startup_module(zend_module_entry *module) /* {{{ */
    2485             : {
    2486       20753 :         if ((module = zend_register_internal_module(module)) != NULL && zend_startup_module_ex(module) == SUCCESS) {
    2487       20753 :                 return SUCCESS;
    2488             :         }
    2489           0 :         return FAILURE;
    2490             : }
    2491             : /* }}} */
    2492             : 
    2493           0 : ZEND_API int zend_get_module_started(const char *module_name) /* {{{ */
    2494             : {
    2495             :         zend_module_entry *module;
    2496             : 
    2497           0 :         module = zend_hash_str_find_ptr(&module_registry, module_name, strlen(module_name));
    2498           0 :         return (module && module->module_started) ? SUCCESS : FAILURE;
    2499             : }
    2500             : /* }}} */
    2501             : 
    2502           0 : static int clean_module_class(zval *el, void *arg) /* {{{ */
    2503             : {
    2504           0 :         zend_class_entry *ce = (zend_class_entry *)Z_PTR_P(el);
    2505           0 :         int module_number = *(int *)arg;
    2506           0 :         if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->module_number == module_number) {
    2507           0 :                 return ZEND_HASH_APPLY_REMOVE;
    2508             :         } else {
    2509           0 :                 return ZEND_HASH_APPLY_KEEP;
    2510             :         }
    2511             : }
    2512             : /* }}} */
    2513             : 
    2514           0 : static void clean_module_classes(int module_number) /* {{{ */
    2515             : {
    2516           0 :         zend_hash_apply_with_argument(EG(class_table), clean_module_class, (void *) &module_number);
    2517           0 : }
    2518             : /* }}} */
    2519             : 
    2520     1445931 : void module_destructor(zend_module_entry *module) /* {{{ */
    2521             : {
    2522             : 
    2523     1445931 :         if (module->type == MODULE_TEMPORARY) {
    2524           0 :                 zend_clean_module_rsrc_dtors(module->module_number);
    2525           0 :                 clean_module_constants(module->module_number);
    2526           0 :                 clean_module_classes(module->module_number);
    2527             :         }
    2528             : 
    2529     1445931 :         if (module->module_started && module->module_shutdown_func) {
    2530             : #if 0
    2531             :                 zend_printf("%s: Module shutdown\n", module->name);
    2532             : #endif
    2533      964035 :                 module->module_shutdown_func(module->type, module->module_number);
    2534             :         }
    2535             : 
    2536             :         /* Deinitilaise module globals */
    2537     1445931 :         if (module->globals_size) {
    2538             : #ifdef ZTS
    2539             :                 if (*module->globals_id_ptr) {
    2540             :                         ts_free_id(*module->globals_id_ptr);
    2541             :                 }
    2542             : #else
    2543      670464 :                 if (module->globals_dtor) {
    2544       83808 :                         module->globals_dtor(module->globals_ptr);
    2545             :                 }
    2546             : #endif
    2547             :         }
    2548             : 
    2549     1445931 :         module->module_started=0;
    2550     1445931 :         if (module->functions) {
    2551     1383075 :                 zend_unregister_functions(module->functions, -1, NULL);
    2552             :         }
    2553             : 
    2554             : #if HAVE_LIBDL
    2555             : #if !(defined(NETWARE) && defined(APACHE_1_BUILD))
    2556     1445931 :         if (module->handle && !getenv("ZEND_DONT_UNLOAD_MODULES")) {
    2557           0 :                 DL_UNLOAD(module->handle);
    2558             :         }
    2559             : #endif
    2560             : #endif
    2561     1445931 : }
    2562             : /* }}} */
    2563             : 
    2564       20873 : ZEND_API void zend_activate_modules(void) /* {{{ */
    2565             : {
    2566       20873 :         zend_module_entry **p = module_request_startup_handlers;
    2567             : 
    2568      354841 :         while (*p) {
    2569      313095 :                 zend_module_entry *module = *p;
    2570             : 
    2571      313095 :                 if (module->request_startup_func(module->type, module->module_number)==FAILURE) {
    2572           0 :                         zend_error(E_WARNING, "request_startup() for %s module failed", module->name);
    2573           0 :                         exit(1);
    2574             :                 }
    2575      313095 :                 p++;
    2576             :         }
    2577       20873 : }
    2578             : /* }}} */
    2579             : 
    2580             : /* call request shutdown for all modules */
    2581           0 : static int module_registry_cleanup(zval *zv) /* {{{ */
    2582             : {
    2583           0 :         zend_module_entry *module = Z_PTR_P(zv);
    2584             : 
    2585           0 :         if (module->request_shutdown_func) {
    2586             : #if 0
    2587             :                 zend_printf("%s: Request shutdown\n", module->name);
    2588             : #endif
    2589           0 :                 module->request_shutdown_func(module->type, module->module_number);
    2590             :         }
    2591           0 :         return 0;
    2592             : }
    2593             : /* }}} */
    2594             : 
    2595       20911 : ZEND_API void zend_deactivate_modules(void) /* {{{ */
    2596             : {
    2597       20911 :         EG(current_execute_data) = NULL; /* we're no longer executing anything */
    2598             : 
    2599       20911 :         zend_try {
    2600       20911 :                 if (EG(full_tables_cleanup)) {
    2601           0 :                         zend_hash_reverse_apply(&module_registry, module_registry_cleanup);
    2602             :                 } else {
    2603       20911 :                         zend_module_entry **p = module_request_shutdown_handlers;
    2604             : 
    2605      460042 :                         while (*p) {
    2606      418220 :                                 zend_module_entry *module = *p;
    2607             : 
    2608      418220 :                                 module->request_shutdown_func(module->type, module->module_number);
    2609      418220 :                                 p++;
    2610             :                         }
    2611             :                 }
    2612       20911 :         } zend_end_try();
    2613       20911 : }
    2614             : /* }}} */
    2615             : 
    2616       20909 : ZEND_API void zend_cleanup_internal_classes(void) /* {{{ */
    2617             : {
    2618       20909 :         zend_class_entry **p = class_cleanup_handlers;
    2619             : 
    2620       41818 :         while (*p) {
    2621           0 :                 zend_cleanup_internal_class_data(*p);
    2622           0 :                 p++;
    2623             :         }
    2624       20909 : }
    2625             : /* }}} */
    2626             : 
    2627           0 : int module_registry_unload_temp(const zend_module_entry *module) /* {{{ */
    2628             : {
    2629           0 :         return (module->type == MODULE_TEMPORARY) ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_STOP;
    2630             : }
    2631             : /* }}} */
    2632             : 
    2633           0 : static int module_registry_unload_temp_wrapper(zval *el) /* {{{ */
    2634             : {
    2635           0 :         zend_module_entry *module = (zend_module_entry *)Z_PTR_P(el);
    2636           0 :         return module_registry_unload_temp((const zend_module_entry *)module);
    2637             : }
    2638             : /* }}} */
    2639             : 
    2640           0 : static int exec_done_cb(zval *el) /* {{{ */
    2641             : {
    2642           0 :         zend_module_entry *module = (zend_module_entry *)Z_PTR_P(el);
    2643           0 :         if (module->post_deactivate_func) {
    2644           0 :                 module->post_deactivate_func();
    2645             :         }
    2646           0 :         return 0;
    2647             : }
    2648             : /* }}} */
    2649             : 
    2650       20911 : ZEND_API void zend_post_deactivate_modules(void) /* {{{ */
    2651             : {
    2652       20911 :         if (EG(full_tables_cleanup)) {
    2653           0 :                 zend_hash_apply(&module_registry, exec_done_cb);
    2654           0 :                 zend_hash_reverse_apply(&module_registry, module_registry_unload_temp_wrapper);
    2655             :         } else {
    2656       20911 :                 zend_module_entry **p = module_post_deactivate_handlers;
    2657             : 
    2658       62733 :                 while (*p) {
    2659       20911 :                         zend_module_entry *module = *p;
    2660             : 
    2661       20911 :                         module->post_deactivate_func();
    2662       20911 :                         p++;
    2663             :                 }
    2664             :         }
    2665       20911 : }
    2666             : /* }}} */
    2667             : 
    2668             : /* return the next free module number */
    2669     1422531 : ZEND_API int zend_next_free_module(void) /* {{{ */
    2670             : {
    2671     1422531 :         return zend_hash_num_elements(&module_registry) + 1;
    2672             : }
    2673             : /* }}} */
    2674             : 
    2675     3911292 : static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class_entry, uint32_t ce_flags) /* {{{ */
    2676             : {
    2677     3911292 :         zend_class_entry *class_entry = malloc(sizeof(zend_class_entry));
    2678     7822584 :         zend_string *lowercase_name = zend_string_alloc(orig_class_entry->name->len, 1);
    2679     3911292 :         *class_entry = *orig_class_entry;
    2680             : 
    2681     3911292 :         class_entry->type = ZEND_INTERNAL_CLASS;
    2682     3911292 :         zend_initialize_class_data(class_entry, 0);
    2683     3911292 :         class_entry->ce_flags = ce_flags | ZEND_ACC_CONSTANTS_UPDATED;
    2684     3911292 :         class_entry->info.internal.module = EG(current_module);
    2685             : 
    2686     3911292 :         if (class_entry->info.internal.builtin_functions) {
    2687     3304728 :                 zend_register_functions(class_entry, class_entry->info.internal.builtin_functions, &class_entry->function_table, MODULE_PERSISTENT);
    2688             :         }
    2689             : 
    2690     3911292 :         zend_str_tolower_copy(lowercase_name->val, orig_class_entry->name->val, class_entry->name->len);
    2691     3911292 :         lowercase_name = zend_new_interned_string(lowercase_name);
    2692     3911292 :         zend_hash_update_ptr(CG(class_table), lowercase_name, class_entry);
    2693             :         zend_string_release(lowercase_name);
    2694     3911292 :         return class_entry;
    2695             : }
    2696             : /* }}} */
    2697             : 
    2698             : /* If parent_ce is not NULL then it inherits from parent_ce
    2699             :  * If parent_ce is NULL and parent_name isn't then it looks for the parent and inherits from it
    2700             :  * If both parent_ce and parent_name are NULL it does a regular class registration
    2701             :  * If parent_name is specified but not found NULL is returned
    2702             :  */
    2703     2133432 : ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce) /* {{{ */
    2704             : {
    2705             :         zend_class_entry *register_class;
    2706             : 
    2707     2133432 :         register_class = zend_register_internal_class(class_entry);
    2708             : 
    2709     2133432 :         if (parent_ce) {
    2710     1610532 :                 zend_do_inheritance(register_class, parent_ce);
    2711             :         }
    2712     2133432 :         return register_class;
    2713             : }
    2714             : /* }}} */
    2715             : 
    2716     1505952 : ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_interfaces, ...) /* {{{ */
    2717             : {
    2718             :         zend_class_entry *interface_entry;
    2719             :         va_list interface_list;
    2720     1505952 :         va_start(interface_list, num_interfaces);
    2721             : 
    2722     4559688 :         while (num_interfaces--) {
    2723     1547784 :                 interface_entry = va_arg(interface_list, zend_class_entry *);
    2724     1547784 :                 zend_do_implement_interface(class_entry, interface_entry);
    2725             :         }
    2726             : 
    2727     1505952 :         va_end(interface_list);
    2728     1505952 : }
    2729             : /* }}} */
    2730             : 
    2731             : /* A class that contains at least one abstract method automatically becomes an abstract class.
    2732             :  */
    2733     3618468 : ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *orig_class_entry) /* {{{ */
    2734             : {
    2735     3618468 :         return do_register_internal_class(orig_class_entry, 0);
    2736             : }
    2737             : /* }}} */
    2738             : 
    2739      292824 : ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry) /* {{{ */
    2740             : {
    2741      292824 :         return do_register_internal_class(orig_class_entry, ZEND_ACC_INTERFACE);
    2742             : }
    2743             : /* }}} */
    2744             : 
    2745          29 : ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce) /* {{{ */
    2746             : {
    2747             :         zend_string *lcname;
    2748             : 
    2749          29 :         if (name[0] == '\\') {
    2750           0 :                 lcname = zend_string_alloc(name_len-1, 1);
    2751           0 :                 zend_str_tolower_copy(lcname->val, name+1, name_len-1);
    2752             :         } else {
    2753          29 :                 lcname = zend_string_alloc(name_len, 1);
    2754          29 :                 zend_str_tolower_copy(lcname->val, name, name_len);
    2755             :         }
    2756             : 
    2757          29 :         zend_assert_valid_class_name(lcname);
    2758             : 
    2759          50 :         ce = zend_hash_add_ptr(CG(class_table), lcname, ce);
    2760             :         zend_string_release(lcname);
    2761          25 :         if (ce) {
    2762          21 :                 ce->refcount++;
    2763          21 :                 return SUCCESS;
    2764             :         }
    2765           4 :         return FAILURE;
    2766             : }
    2767             : /* }}} */
    2768             : 
    2769           0 : ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_length, zend_bool is_ref, int num_symbol_tables, ...) /* {{{ */
    2770             : {
    2771             :         HashTable *symbol_table;
    2772             :         va_list symbol_table_list;
    2773             : 
    2774           0 :         if (num_symbol_tables <= 0) return FAILURE;
    2775             : 
    2776           0 :         if (is_ref) {
    2777           0 :                 ZVAL_MAKE_REF(symbol);
    2778             :         }
    2779             : 
    2780           0 :         va_start(symbol_table_list, num_symbol_tables);
    2781           0 :         while (num_symbol_tables-- > 0) {
    2782           0 :                 symbol_table = va_arg(symbol_table_list, HashTable *);
    2783           0 :                 zend_hash_str_update(symbol_table, name, name_length, symbol);
    2784           0 :                 if (Z_REFCOUNTED_P(symbol)) {
    2785             :                         Z_ADDREF_P(symbol);
    2786             :                 }
    2787             :         }
    2788           0 :         va_end(symbol_table_list);
    2789           0 :         return SUCCESS;
    2790             : }
    2791             : /* }}} */
    2792             : 
    2793             : /* Disabled functions support */
    2794             : 
    2795             : /* {{{ proto void display_disabled_function(void)
    2796             : Dummy function which displays an error when a disabled function is called. */
    2797           6 : ZEND_API ZEND_FUNCTION(display_disabled_function)
    2798             : {
    2799           6 :         zend_error(E_WARNING, "%s() has been disabled for security reasons", get_active_function_name());
    2800           6 : }
    2801             : /* }}} */
    2802             : 
    2803           8 : ZEND_API int zend_disable_function(char *function_name, size_t function_name_length) /* {{{ */
    2804             : {
    2805             :         zend_internal_function *func;
    2806          16 :         if ((func = zend_hash_str_find_ptr(CG(function_table), function_name, function_name_length))) {
    2807           8 :             func->fn_flags &= ~(ZEND_ACC_VARIADIC | ZEND_ACC_HAS_TYPE_HINTS);
    2808           8 :                 func->num_args = 0;
    2809           8 :                 func->arg_info = NULL;
    2810           8 :                 func->handler = ZEND_FN(display_disabled_function);
    2811           8 :                 return SUCCESS;
    2812             :         }
    2813           0 :         return FAILURE;
    2814             : }
    2815             : /* }}} */
    2816             : 
    2817             : #ifdef ZEND_WIN32
    2818             : #pragma optimize("", off)
    2819             : #endif
    2820           1 : static zend_object *display_disabled_class(zend_class_entry *class_type) /* {{{ */
    2821             : {
    2822             :         zend_object *intern;
    2823             : 
    2824           1 :         intern = zend_objects_new(class_type);
    2825           1 :         zend_error(E_WARNING, "%s() has been disabled for security reasons", class_type->name->val);
    2826           1 :         return intern;
    2827             : }
    2828             : #ifdef ZEND_WIN32
    2829             : #pragma optimize("", on)
    2830             : #endif
    2831             : /* }}} */
    2832             : 
    2833             : static const zend_function_entry disabled_class_new[] = {
    2834             :         ZEND_FE_END
    2835             : };
    2836             : 
    2837           1 : ZEND_API int zend_disable_class(char *class_name, size_t class_name_length) /* {{{ */
    2838             : {
    2839             :         zend_class_entry *disabled_class;
    2840             :         zend_string *key;
    2841             : 
    2842           1 :         key = zend_string_alloc(class_name_length, 0);
    2843           1 :         zend_str_tolower_copy(key->val, class_name, class_name_length);
    2844           2 :         disabled_class = zend_hash_find_ptr(CG(class_table), key);
    2845           1 :         if (!disabled_class) {
    2846           0 :                 return FAILURE;
    2847             :         }
    2848           1 :         INIT_CLASS_ENTRY_INIT_METHODS((*disabled_class), disabled_class_new, NULL, NULL, NULL, NULL, NULL);
    2849           1 :         disabled_class->create_object = display_disabled_class;
    2850           1 :         zend_hash_clean(&disabled_class->function_table);
    2851           1 :         return SUCCESS;
    2852             : }
    2853             : /* }}} */
    2854             : 
    2855         353 : static int zend_is_callable_check_class(zend_string *name, zend_fcall_info_cache *fcc, int *strict_class, char **error) /* {{{ */
    2856             : {
    2857         353 :         int ret = 0;
    2858             :         zend_class_entry *ce;
    2859         353 :         size_t name_len = name->len;
    2860             :         zend_string *lcname;
    2861             :         ALLOCA_FLAG(use_heap);
    2862             : 
    2863         353 :         STR_ALLOCA_ALLOC(lcname, name_len, use_heap);
    2864         353 :         zend_str_tolower_copy(lcname->val, name->val, name_len);
    2865             : 
    2866         353 :         *strict_class = 0;
    2867         370 :         if (zend_string_equals_literal(lcname, "self")) {
    2868          17 :                 if (!EG(scope)) {
    2869           3 :                         if (error) *error = estrdup("cannot access self:: when no class scope is active");
    2870             :                 } else {
    2871          14 :                         fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
    2872          14 :                         fcc->calling_scope = EG(scope);
    2873          14 :                         if (!fcc->object) {
    2874          11 :                                 fcc->object = zend_get_this_object(EG(current_execute_data));
    2875             :                         }
    2876          14 :                         ret = 1;
    2877             :                 }
    2878         372 :         } else if (zend_string_equals_literal(lcname, "parent")) {
    2879          36 :                 if (!EG(scope)) {
    2880           0 :                         if (error) *error = estrdup("cannot access parent:: when no class scope is active");
    2881          36 :                 } else if (!EG(scope)->parent) {
    2882           0 :                         if (error) *error = estrdup("cannot access parent:: when current class scope has no parent");
    2883             :                 } else {
    2884          36 :                         fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
    2885          36 :                         fcc->calling_scope = EG(scope)->parent;
    2886          36 :                         if (!fcc->object) {
    2887          18 :                                 fcc->object = zend_get_this_object(EG(current_execute_data));
    2888             :                         }
    2889          36 :                         *strict_class = 1;
    2890          36 :                         ret = 1;
    2891             :                 }
    2892         312 :         } else if (zend_string_equals_literal(lcname, "static")) {
    2893          12 :                 zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data));
    2894             : 
    2895          12 :                 if (!called_scope) {
    2896           0 :                         if (error) *error = estrdup("cannot access static:: when no class scope is active");
    2897             :                 } else {
    2898          12 :                         fcc->called_scope = called_scope;
    2899          12 :                         fcc->calling_scope = called_scope;
    2900          12 :                         if (!fcc->object) {
    2901          11 :                                 fcc->object = zend_get_this_object(EG(current_execute_data));
    2902             :                         }
    2903          12 :                         *strict_class = 1;
    2904          12 :                         ret = 1;
    2905             :                 }
    2906         288 :         } else if ((ce = zend_lookup_class_ex(name, NULL, 1)) != NULL) {
    2907             :                 zend_class_entry *scope;
    2908         275 :                 zend_execute_data *ex = EG(current_execute_data);
    2909             : 
    2910         767 :                 while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
    2911         217 :                         ex = ex->prev_execute_data;
    2912             :                 }
    2913         275 :                 scope = ex ? ex->func->common.scope : NULL;
    2914         275 :                 fcc->calling_scope = ce;
    2915         317 :                 if (scope && !fcc->object) {
    2916          42 :                         zend_object *object = zend_get_this_object(EG(current_execute_data));
    2917             : 
    2918         124 :                         if (object &&
    2919          29 :                             instanceof_function(object->ce, scope) &&
    2920          29 :                             instanceof_function(scope, fcc->calling_scope)) {
    2921          24 :                                 fcc->object = object;
    2922          24 :                                 fcc->called_scope = object->ce;
    2923             :                         } else {
    2924          18 :                                 fcc->called_scope = fcc->calling_scope;
    2925             :                         }
    2926             :                 } else {
    2927         233 :                         fcc->called_scope = fcc->object ? fcc->object->ce : fcc->calling_scope;
    2928             :                 }
    2929         275 :                 *strict_class = 1;
    2930         275 :                 ret = 1;
    2931             :         } else {
    2932          12 :                 if (error) zend_spprintf(error, 0, "class '%.*s' not found", name_len, name->val);
    2933             :         }
    2934         352 :         STR_ALLOCA_FREE(lcname, use_heap);
    2935         352 :         return ret;
    2936             : }
    2937             : /* }}} */
    2938             : 
    2939      232929 : static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fcall_info_cache *fcc, int strict_class, char **error) /* {{{ */
    2940             : {
    2941      232929 :         zend_class_entry *ce_org = fcc->calling_scope;
    2942      232929 :         int retval = 0;
    2943             :         zend_string *mname, *cname;
    2944             :         zend_string *lmname;
    2945             :         const char *colon;
    2946             :         size_t clen, mlen;
    2947             :         zend_class_entry *last_scope;
    2948             :         HashTable *ftable;
    2949      232929 :         int call_via_handler = 0;
    2950             :         ALLOCA_FLAG(use_heap)
    2951             : 
    2952      232929 :         if (error) {
    2953      232175 :                 *error = NULL;
    2954             :         }
    2955             : 
    2956      232929 :         fcc->calling_scope = NULL;
    2957      232929 :         fcc->function_handler = NULL;
    2958             : 
    2959      232929 :         if (!ce_org) {
    2960             :                 zend_string *lmname;
    2961             : 
    2962             :                 /* Skip leading \ */
    2963      223623 :                 if (UNEXPECTED(Z_STRVAL_P(callable)[0] == '\\')) {
    2964          19 :                         STR_ALLOCA_INIT(lmname, Z_STRVAL_P(callable) + 1, Z_STRLEN_P(callable) - 1, use_heap);
    2965             :                 } else {
    2966      223604 :                         lmname = Z_STR_P(callable);
    2967             :                 }
    2968             :                 /* Check if function with given name exists.
    2969             :                  * This may be a compound name that includes namespace name */
    2970      447246 :                 if (EXPECTED((fcc->function_handler = zend_hash_find_ptr(EG(function_table), lmname)) != NULL)) {
    2971      223105 :                         if (lmname != Z_STR_P(callable)) {
    2972           2 :                                 STR_ALLOCA_FREE(lmname, use_heap);
    2973             :                         }
    2974      223105 :                         return 1;
    2975             :                 } else {
    2976         518 :                         if (lmname == Z_STR_P(callable)) {
    2977         501 :                                 STR_ALLOCA_INIT(lmname, Z_STRVAL_P(callable), Z_STRLEN_P(callable), use_heap);
    2978             :                         } else {
    2979             :                                 zend_string_forget_hash_val(lmname);
    2980             :                         }
    2981         518 :                         zend_str_tolower(lmname->val, lmname->len);
    2982        1036 :                         if ((fcc->function_handler = zend_hash_find_ptr(EG(function_table), lmname)) != NULL) {
    2983         205 :                                 STR_ALLOCA_FREE(lmname, use_heap);
    2984         205 :                                 return 1;
    2985             :                         }
    2986             :                 }
    2987         313 :                 if (lmname != Z_STR_P(callable)) {
    2988         313 :                         STR_ALLOCA_FREE(lmname, use_heap);
    2989             :                 }
    2990             :         }
    2991             : 
    2992             :         /* Split name into class/namespace and method/function names */
    2993       19614 :         if ((colon = zend_memrchr(Z_STRVAL_P(callable), ':', Z_STRLEN_P(callable))) != NULL &&
    2994         127 :                 colon > Z_STRVAL_P(callable) &&
    2995         127 :                 *(colon-1) == ':'
    2996             :         ) {
    2997         127 :                 colon--;
    2998         127 :                 clen = colon - Z_STRVAL_P(callable);
    2999         127 :                 mlen = Z_STRLEN_P(callable) - clen - 2;
    3000             : 
    3001         127 :                 if (colon == Z_STRVAL_P(callable)) {
    3002           0 :                         if (error) zend_spprintf(error, 0, "invalid function name");
    3003           0 :                         return 0;
    3004             :                 }
    3005             : 
    3006             :                 /* This is a compound name.
    3007             :                  * Try to fetch class and then find static method. */
    3008         127 :                 last_scope = EG(scope);
    3009         127 :                 if (ce_org) {
    3010          28 :                         EG(scope) = ce_org;
    3011             :                 }
    3012             : 
    3013         254 :                 cname = zend_string_init(Z_STRVAL_P(callable), clen, 0);
    3014         127 :                 if (!zend_is_callable_check_class(cname, fcc, &strict_class, error)) {
    3015             :                         zend_string_release(cname);
    3016           3 :                         EG(scope) = last_scope;
    3017           3 :                         return 0;
    3018             :                 }
    3019             :                 zend_string_release(cname);
    3020         123 :                 EG(scope) = last_scope;
    3021             : 
    3022         123 :                 ftable = &fcc->calling_scope->function_table;
    3023         123 :                 if (ce_org && !instanceof_function(ce_org, fcc->calling_scope)) {
    3024           1 :                         if (error) zend_spprintf(error, 0, "class '%s' is not a subclass of '%s'", ce_org->name->val, fcc->calling_scope->name->val);
    3025           1 :                         return 0;
    3026             :                 }
    3027         244 :                 mname = zend_string_init(Z_STRVAL_P(callable) + clen + 2, mlen, 0);
    3028        9492 :         } else if (ce_org) {
    3029             :                 /* Try to fetch find static method of given class. */
    3030        9278 :                 mlen = Z_STRLEN_P(callable);
    3031        9278 :                 mname = Z_STR_P(callable);
    3032             :                 zend_string_addref(mname);
    3033        9278 :                 ftable = &ce_org->function_table;
    3034        9278 :                 fcc->calling_scope = ce_org;
    3035             :         } else {
    3036             :                 /* We already checked for plain function before. */
    3037         214 :                 if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) {
    3038         187 :                         zend_spprintf(error, 0, "function '%s' not found or invalid function name", Z_STRVAL_P(callable));
    3039             :                 }
    3040         214 :                 return 0;
    3041             :         }
    3042             : 
    3043        9400 :         lmname = zend_string_tolower(mname);
    3044       10060 :         if (strict_class &&
    3045         318 :             fcc->calling_scope &&
    3046         333 :                 zend_string_equals_literal(lmname, ZEND_CONSTRUCTOR_FUNC_NAME)) {
    3047           9 :                 fcc->function_handler = fcc->calling_scope->constructor;
    3048           9 :                 if (fcc->function_handler) {
    3049           9 :                         retval = 1;
    3050             :                 }
    3051        9391 :         } else if ((fcc->function_handler = zend_hash_find_ptr(ftable, lmname)) != NULL) {
    3052        9088 :                 retval = 1;
    3053        9092 :                 if ((fcc->function_handler->op_array.fn_flags & ZEND_ACC_CHANGED) &&
    3054           3 :                     !strict_class && EG(scope) &&
    3055           1 :                     instanceof_function(fcc->function_handler->common.scope, EG(scope))) {
    3056             :                         zend_function *priv_fbc;
    3057             : 
    3058           4 :                         if ((priv_fbc = zend_hash_find_ptr(&EG(scope)->function_table, lmname)) != NULL
    3059             :                                 && priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
    3060           2 :                                 && priv_fbc->common.scope == EG(scope)) {
    3061           1 :                                 fcc->function_handler = priv_fbc;
    3062             :                         }
    3063             :                 }
    3064       45026 :                 if ((check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0 &&
    3065        9085 :                     (fcc->calling_scope &&
    3066       17923 :                      ((fcc->object && fcc->calling_scope->__call) ||
    3067        8930 :                       (!fcc->object && fcc->calling_scope->__callstatic)))) {
    3068         410 :                         if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
    3069           2 :                                 if (!zend_check_private(fcc->function_handler, fcc->object ? fcc->object->ce : EG(scope), lmname)) {
    3070           1 :                                         retval = 0;
    3071           1 :                                         fcc->function_handler = NULL;
    3072           1 :                                         goto get_function_via_handler;
    3073             :                                 }
    3074         408 :                         } else if (fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED) {
    3075           2 :                                 if (!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) {
    3076           1 :                                         retval = 0;
    3077           1 :                                         fcc->function_handler = NULL;
    3078           1 :                                         goto get_function_via_handler;
    3079             :                                 }
    3080             :                         }
    3081             :                 }
    3082             :         } else {
    3083             : get_function_via_handler:
    3084         580 :                 if (fcc->object && fcc->calling_scope == ce_org) {
    3085         278 :                         if (strict_class && ce_org->__call) {
    3086           3 :                                 fcc->function_handler = zend_get_call_trampoline_func(ce_org, mname, 0);
    3087           3 :                                 call_via_handler = 1;
    3088           3 :                                 retval = 1;
    3089         272 :                         } else if (fcc->object->handlers->get_method) {
    3090         272 :                                 fcc->function_handler = fcc->object->handlers->get_method(&fcc->object, mname, NULL);
    3091         272 :                                 if (fcc->function_handler) {
    3092          30 :                                         if (strict_class &&
    3093           0 :                                             (!fcc->function_handler->common.scope ||
    3094           0 :                                              !instanceof_function(ce_org, fcc->function_handler->common.scope))) {
    3095           0 :                                                 if (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
    3096           0 :                                                         if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
    3097           0 :                                                                 zend_string_release(fcc->function_handler->common.function_name);
    3098             :                                                         }
    3099           0 :                                                         zend_free_trampoline(fcc->function_handler);
    3100             :                                                 }
    3101             :                                         } else {
    3102          30 :                                                 retval = 1;
    3103          30 :                                                 call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
    3104             :                                         }
    3105             :                                 }
    3106             :                         }
    3107          30 :                 } else if (fcc->calling_scope) {
    3108          30 :                         if (fcc->calling_scope->get_static_method) {
    3109           0 :                                 fcc->function_handler = fcc->calling_scope->get_static_method(fcc->calling_scope, mname);
    3110             :                         } else {
    3111          30 :                                 fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, mname, NULL);
    3112             :                         }
    3113          30 :                         if (fcc->function_handler) {
    3114          15 :                                 retval = 1;
    3115          15 :                                 call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
    3116          15 :                                 if (call_via_handler && !fcc->object) {
    3117          10 :                                         zend_object *object = zend_get_this_object(EG(current_execute_data));
    3118          12 :                                         if (object &&
    3119           2 :                                             instanceof_function(object->ce, fcc->calling_scope)) {
    3120           2 :                                                 fcc->object = object;
    3121             :                                         }
    3122             :                                 }
    3123             :                         }
    3124             :                 }
    3125             :         }
    3126             : 
    3127        9400 :         if (retval) {
    3128        9143 :                 if (fcc->calling_scope && !call_via_handler) {
    3129        9099 :                         if (!fcc->object && (fcc->function_handler->common.fn_flags & ZEND_ACC_ABSTRACT)) {
    3130           5 :                                 if (error) {
    3131           4 :                                         zend_spprintf(error, 0, "cannot call abstract method %s::%s()", fcc->calling_scope->name->val, fcc->function_handler->common.function_name->val);
    3132           4 :                                         retval = 0;
    3133             :                                 } else {
    3134           1 :                                         zend_error(E_EXCEPTION | E_ERROR, "Cannot call abstract method %s::%s()", fcc->calling_scope->name->val, fcc->function_handler->common.function_name->val);
    3135           1 :                                         return 0;
    3136             :                                 }
    3137        9090 :                         } else if (!fcc->object && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) {
    3138             :                                 int severity;
    3139             :                                 char *verb;
    3140          52 :                                 if (fcc->function_handler->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
    3141          49 :                                         severity = E_DEPRECATED;
    3142          49 :                                         verb = "should not";
    3143             :                                 } else {
    3144             :                                         /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
    3145           3 :                                         severity = E_EXCEPTION | E_ERROR;
    3146           3 :                                         verb = "cannot";
    3147             :                                 }
    3148          52 :                                 if ((check_flags & IS_CALLABLE_CHECK_IS_STATIC) != 0) {
    3149           5 :                                         retval = 0;
    3150             :                                 }
    3151          52 :                                 if (error) {
    3152          47 :                                         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);
    3153          47 :                                         if (severity != E_DEPRECATED) {
    3154           1 :                                                 retval = 0;
    3155             :                                         }
    3156           5 :                                 } else if (retval) {
    3157           5 :                                         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);
    3158             :                                 }
    3159             :                         }
    3160        9093 :                         if (retval && (check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) {
    3161        9080 :                                 if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
    3162          30 :                                         if (!zend_check_private(fcc->function_handler, fcc->object ? fcc->object->ce : EG(scope), lmname)) {
    3163          21 :                                                 if (error) {
    3164          21 :                                                         if (*error) {
    3165           3 :                                                                 efree(*error);
    3166             :                                                         }
    3167          21 :                                                         zend_spprintf(error, 0, "cannot access private method %s::%s()", fcc->calling_scope->name->val, fcc->function_handler->common.function_name->val);
    3168             :                                                 }
    3169          21 :                                                 retval = 0;
    3170             :                                         }
    3171        9050 :                                 } else if ((fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED)) {
    3172          25 :                                         if (!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) {
    3173          18 :                                                 if (error) {
    3174          18 :                                                         if (*error) {
    3175           1 :                                                                 efree(*error);
    3176             :                                                         }
    3177          18 :                                                         zend_spprintf(error, 0, "cannot access protected method %s::%s()", fcc->calling_scope->name->val, fcc->function_handler->common.function_name->val);
    3178             :                                                 }
    3179          18 :                                                 retval = 0;
    3180             :                                         }
    3181             :                                 }
    3182             :                         }
    3183             :                 }
    3184         257 :         } else if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) {
    3185         132 :                 if (fcc->calling_scope) {
    3186         132 :                         if (error) zend_spprintf(error, 0, "class '%s' does not have a method '%s'", fcc->calling_scope->name->val, mname->val);
    3187             :                 } else {
    3188           0 :                         if (error) zend_spprintf(error, 0, "function '%s' does not exist", mname->val);
    3189             :                 }
    3190             :         }
    3191             :         zend_string_release(lmname);
    3192             :         zend_string_release(mname);
    3193             : 
    3194        9398 :         if (fcc->object) {
    3195        9129 :                 fcc->called_scope = fcc->object->ce;
    3196             :         }
    3197        9398 :         if (retval) {
    3198        9092 :                 fcc->initialized = 1;
    3199             :         }
    3200        9398 :         return retval;
    3201             : }
    3202             : /* }}} */
    3203             : 
    3204      234399 : 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) /* {{{ */
    3205             : {
    3206             :         zend_bool ret;
    3207             :         zend_fcall_info_cache fcc_local;
    3208             : 
    3209      234399 :         if (callable_name) {
    3210      230931 :                 *callable_name = NULL;
    3211             :         }
    3212      234399 :         if (fcc == NULL) {
    3213        1523 :                 fcc = &fcc_local;
    3214             :         }
    3215      234399 :         if (error) {
    3216      233461 :                 *error = NULL;
    3217             :         }
    3218             : 
    3219      234399 :         fcc->initialized = 0;
    3220      234399 :         fcc->calling_scope = NULL;
    3221      234399 :         fcc->called_scope = NULL;
    3222      234399 :         fcc->function_handler = NULL;
    3223      234399 :         fcc->object = NULL;
    3224             : 
    3225      251209 :         if (object &&
    3226        8405 :             (!EG(objects_store).object_buckets ||
    3227        8405 :              !IS_OBJ_VALID(EG(objects_store).object_buckets[object->handle]))) {
    3228           0 :                 return 0;
    3229             :         }
    3230             : 
    3231             : again:
    3232      234400 :         switch (Z_TYPE_P(callable)) {
    3233             :                 case IS_STRING:
    3234      232082 :                         if (object) {
    3235        8400 :                                 fcc->object = object;
    3236        8400 :                                 fcc->calling_scope = object->ce;
    3237        8400 :                                 if (callable_name) {
    3238             :                                         char *ptr;
    3239             : 
    3240       16788 :                                         *callable_name = zend_string_alloc(fcc->calling_scope->name->len + Z_STRLEN_P(callable) + sizeof("::") - 1, 0);
    3241        8394 :                                         ptr = (*callable_name)->val;
    3242        8394 :                                         memcpy(ptr, fcc->calling_scope->name->val, fcc->calling_scope->name->len);
    3243        8394 :                                         ptr += fcc->calling_scope->name->len;
    3244        8394 :                                         memcpy(ptr, "::", sizeof("::") - 1);
    3245        8394 :                                         ptr += sizeof("::") - 1;
    3246        8394 :                                         memcpy(ptr, Z_STRVAL_P(callable), Z_STRLEN_P(callable) + 1);
    3247             :                                 }
    3248      223682 :                         } else if (callable_name) {
    3249      442894 :                                 *callable_name = zend_string_copy(Z_STR_P(callable));
    3250             :                         }
    3251      232082 :                         if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
    3252          59 :                                 fcc->called_scope = fcc->calling_scope;
    3253          59 :                                 return 1;
    3254             :                         }
    3255             : 
    3256      232023 :                         ret = zend_is_callable_check_func(check_flags, callable, fcc, 0, error);
    3257      234416 :                         if (fcc == &fcc_local &&
    3258         669 :                             fcc->function_handler &&
    3259         575 :                                 ((fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) ||
    3260         575 :                              fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
    3261         575 :                              fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
    3262           0 :                                 if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
    3263           0 :                                         zend_string_release(fcc->function_handler->common.function_name);
    3264             :                                 }
    3265           0 :                                 zend_free_trampoline(fcc->function_handler);
    3266             :                         }
    3267      232022 :                         return ret;
    3268             : 
    3269             :                 case IS_ARRAY:
    3270             :                         {
    3271        1249 :                                 zval *method = NULL;
    3272        1249 :                                 zval *obj = NULL;
    3273        1249 :                                 int strict_class = 0;
    3274             : 
    3275        1249 :                                 if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
    3276        1170 :                                         obj = zend_hash_index_find(Z_ARRVAL_P(callable), 0);
    3277        1170 :                                         method = zend_hash_index_find(Z_ARRVAL_P(callable), 1);
    3278             :                                 }
    3279             : 
    3280             :                                 do {
    3281        1249 :                                         if (obj == NULL || method == NULL) {
    3282             :                                                 break;
    3283             :                                         }
    3284             : 
    3285        1149 :                                         ZVAL_DEREF(method);
    3286        1149 :                                         if (Z_TYPE_P(method) != IS_STRING) {
    3287          46 :                                                 break;
    3288             :                                         }
    3289             : 
    3290        1103 :                                         ZVAL_DEREF(obj);
    3291        1103 :                                         if (Z_TYPE_P(obj) == IS_STRING) {
    3292         244 :                                                 if (callable_name) {
    3293             :                                                         char *ptr;
    3294             : 
    3295             : 
    3296         134 :                                                         *callable_name = zend_string_alloc(Z_STRLEN_P(obj) + Z_STRLEN_P(method) + sizeof("::") - 1, 0);
    3297          67 :                                                         ptr = (*callable_name)->val;
    3298          67 :                                                         memcpy(ptr, Z_STRVAL_P(obj), Z_STRLEN_P(obj));
    3299          67 :                                                         ptr += Z_STRLEN_P(obj);
    3300          67 :                                                         memcpy(ptr, "::", sizeof("::") - 1);
    3301          67 :                                                         ptr += sizeof("::") - 1;
    3302          67 :                                                         memcpy(ptr, Z_STRVAL_P(method), Z_STRLEN_P(method) + 1);
    3303             :                                                 }
    3304             : 
    3305         244 :                                                 if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
    3306          18 :                                                         return 1;
    3307             :                                                 }
    3308             : 
    3309         226 :                                                 if (!zend_is_callable_check_class(Z_STR_P(obj), fcc, &strict_class, error)) {
    3310          12 :                                                         return 0;
    3311             :                                                 }
    3312             : 
    3313         859 :                                         } else if (Z_TYPE_P(obj) == IS_OBJECT) {
    3314        1616 :                                                 if (!EG(objects_store).object_buckets ||
    3315         808 :                                                     !IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(obj)])) {
    3316           0 :                                                         return 0;
    3317             :                                                 }
    3318             : 
    3319         808 :                                                 fcc->calling_scope = Z_OBJCE_P(obj); /* TBFixed: what if it's overloaded? */
    3320             : 
    3321         808 :                                                 fcc->object = Z_OBJ_P(obj);
    3322             : 
    3323         808 :                                                 if (callable_name) {
    3324             :                                                         char *ptr;
    3325             : 
    3326         984 :                                                         *callable_name = zend_string_alloc(fcc->calling_scope->name->len + Z_STRLEN_P(method) + sizeof("::") - 1, 0);
    3327         492 :                                                         ptr = (*callable_name)->val;
    3328         492 :                                                         memcpy(ptr, fcc->calling_scope->name->val, fcc->calling_scope->name->len);
    3329         492 :                                                         ptr += fcc->calling_scope->name->len;
    3330         492 :                                                         memcpy(ptr, "::", sizeof("::") - 1);
    3331         492 :                                                         ptr += sizeof("::") - 1;
    3332         492 :                                                         memcpy(ptr, Z_STRVAL_P(method), Z_STRLEN_P(method) + 1);
    3333             :                                                 }
    3334             : 
    3335         808 :                                                 if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
    3336         116 :                                                         fcc->called_scope = fcc->calling_scope;
    3337         116 :                                                         return 1;
    3338             :                                                 }
    3339             :                                         } else {
    3340          51 :                                                 break;
    3341             :                                         }
    3342             : 
    3343         906 :                                         ret = zend_is_callable_check_func(check_flags, method, fcc, strict_class, error);
    3344        1975 :                                         if (fcc == &fcc_local &&
    3345         357 :                                             fcc->function_handler &&
    3346         239 :                                                 ((fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) ||
    3347         237 :                                              fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
    3348         237 :                                              fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
    3349           2 :                                                 if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
    3350           2 :                                                         zend_string_release(fcc->function_handler->common.function_name);
    3351             :                                                 }
    3352           2 :                                                 zend_free_trampoline(fcc->function_handler);
    3353             :                                         }
    3354         905 :                                         return ret;
    3355             : 
    3356             :                                 } while (0);
    3357         197 :                                 if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
    3358         430 :                                         if (!obj || (!Z_ISREF_P(obj)?
    3359         194 :                                                                 (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) :
    3360           0 :                                                                 (Z_TYPE_P(Z_REFVAL_P(obj)) != IS_STRING && Z_TYPE_P(Z_REFVAL_P(obj)) != IS_OBJECT))) {
    3361         116 :                                                 if (error) zend_spprintf(error, 0, "first array member is not a valid class name or object");
    3362             :                                         } else {
    3363           2 :                                                 if (error) zend_spprintf(error, 0, "second array member is not a valid method");
    3364             :                                         }
    3365             :                                 } else {
    3366          79 :                                         if (error) zend_spprintf(error, 0, "array must have exactly two members");
    3367             :                                 }
    3368         197 :                                 if (callable_name) {
    3369          45 :                                         *callable_name = zend_string_init("Array", sizeof("Array")-1, 0);
    3370             :                                 }
    3371             :                         }
    3372         197 :                         return 0;
    3373             :                 case IS_OBJECT:
    3374         544 :                         if (Z_OBJ_HANDLER_P(callable, get_closure) && Z_OBJ_HANDLER_P(callable, get_closure)(callable, &fcc->calling_scope, &fcc->function_handler, &fcc->object) == SUCCESS) {
    3375         494 :                                 fcc->called_scope = fcc->calling_scope;
    3376         494 :                                 if (callable_name) {
    3377         440 :                                         zend_class_entry *ce = Z_OBJCE_P(callable); /* TBFixed: what if it's overloaded? */
    3378             : 
    3379         880 :                                         *callable_name = zend_string_alloc(ce->name->len + sizeof("::__invoke") - 1, 0);
    3380         440 :                                         memcpy((*callable_name)->val, ce->name->val, ce->name->len);
    3381         440 :                                         memcpy((*callable_name)->val + ce->name->len, "::__invoke", sizeof("::__invoke"));
    3382             :                                 }
    3383         494 :                                 return 1;
    3384             :                         }
    3385          50 :                         if (callable_name) {
    3386           1 :                                 *callable_name = zval_get_string(callable);
    3387             :                         }
    3388          50 :                         if (error) zend_spprintf(error, 0, "no array or string given");
    3389          50 :                         return 0;
    3390             :                 case IS_REFERENCE:
    3391           1 :                         callable = Z_REFVAL_P(callable);
    3392           1 :                         goto again;
    3393             :                 default:
    3394         524 :                         if (callable_name) {
    3395          45 :                                 *callable_name = zval_get_string(callable);
    3396             :                         }
    3397         524 :                         if (error) zend_spprintf(error, 0, "no array or string given");
    3398         524 :                         return 0;
    3399             :         }
    3400             : }
    3401             : /* }}} */
    3402             : 
    3403         877 : ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, zend_string **callable_name) /* {{{ */
    3404             : {
    3405         877 :         return zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, NULL);
    3406             : }
    3407             : /* }}} */
    3408             : 
    3409          30 : ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_name) /* {{{ */
    3410             : {
    3411             :         zend_fcall_info_cache fcc;
    3412             : 
    3413          30 :         if (zend_is_callable_ex(callable, NULL, IS_CALLABLE_STRICT, callable_name, &fcc, NULL)) {
    3414          28 :                 if (Z_TYPE_P(callable) == IS_STRING && fcc.calling_scope) {
    3415             :                         zval_dtor(callable);
    3416           1 :                         array_init(callable);
    3417           2 :                         add_next_index_str(callable, zend_string_copy(fcc.calling_scope->name));
    3418           2 :                         add_next_index_str(callable, zend_string_copy(fcc.function_handler->common.function_name));
    3419             :                 }
    3420         112 :                 if (fcc.function_handler &&
    3421          28 :                         ((fcc.function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) ||
    3422          28 :                      fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
    3423          28 :                      fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
    3424           0 :                         if (fcc.function_handler->type != ZEND_OVERLOADED_FUNCTION) {
    3425           0 :                                 zend_string_release(fcc.function_handler->common.function_name);
    3426             :                         }
    3427           0 :                         zend_free_trampoline(fcc.function_handler);
    3428             :                 }
    3429          28 :                 return 1;
    3430             :         }
    3431           1 :         return 0;
    3432             : }
    3433             : /* }}} */
    3434             : 
    3435        2852 : 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) /* {{{ */
    3436             : {
    3437        2852 :         if (!zend_is_callable_ex(callable, NULL, check_flags, callable_name, fcc, error)) {
    3438         716 :                 return FAILURE;
    3439             :         }
    3440             : 
    3441        2136 :         fci->size = sizeof(*fci);
    3442        2136 :         fci->function_table = fcc->calling_scope ? &fcc->calling_scope->function_table : EG(function_table);
    3443        2136 :         fci->object = fcc->object;
    3444        2136 :         ZVAL_COPY_VALUE(&fci->function_name, callable);
    3445        2136 :         fci->retval = NULL;
    3446        2136 :         fci->param_count = 0;
    3447        2136 :         fci->params = NULL;
    3448        2136 :         fci->no_separation = 1;
    3449        2136 :         fci->symbol_table = NULL;
    3450             : 
    3451        2136 :         return SUCCESS;
    3452             : }
    3453             : /* }}} */
    3454             : 
    3455         530 : ZEND_API void zend_fcall_info_args_clear(zend_fcall_info *fci, int free_mem) /* {{{ */
    3456             : {
    3457         530 :         if (fci->params) {
    3458         185 :                 zval *p = fci->params;
    3459         185 :                 zval *end = p + fci->param_count;
    3460             : 
    3461         686 :                 while (p != end) {
    3462             :                         i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
    3463         316 :                         p++;
    3464             :                 }
    3465         185 :                 if (free_mem) {
    3466         185 :                         efree(fci->params);
    3467         185 :                         fci->params = NULL;
    3468             :                 }
    3469             :         }
    3470         530 :         fci->param_count = 0;
    3471         530 : }
    3472             : /* }}} */
    3473             : 
    3474           0 : ZEND_API void zend_fcall_info_args_save(zend_fcall_info *fci, int *param_count, zval **params) /* {{{ */
    3475             : {
    3476           0 :         *param_count = fci->param_count;
    3477           0 :         *params = fci->params;
    3478           0 :         fci->param_count = 0;
    3479           0 :         fci->params = NULL;
    3480           0 : }
    3481             : /* }}} */
    3482             : 
    3483           0 : ZEND_API void zend_fcall_info_args_restore(zend_fcall_info *fci, int param_count, zval *params) /* {{{ */
    3484             : {
    3485           0 :         zend_fcall_info_args_clear(fci, 1);
    3486           0 :         fci->param_count = param_count;
    3487           0 :         fci->params = params;
    3488           0 : }
    3489             : /* }}} */
    3490             : 
    3491         194 : ZEND_API int zend_fcall_info_args_ex(zend_fcall_info *fci, zend_function *func, zval *args) /* {{{ */
    3492             : {
    3493             :         zval *arg, *params;
    3494         194 :         uint32_t n = 1;
    3495             : 
    3496         194 :         zend_fcall_info_args_clear(fci, !args);
    3497             : 
    3498         194 :         if (!args) {
    3499          11 :                 return SUCCESS;
    3500             :         }
    3501             : 
    3502         183 :         if (Z_TYPE_P(args) != IS_ARRAY) {
    3503         113 :                 return FAILURE;
    3504             :         }
    3505             : 
    3506          70 :         fci->param_count = zend_hash_num_elements(Z_ARRVAL_P(args));
    3507          70 :         fci->params = params = (zval *) erealloc(fci->params, fci->param_count * sizeof(zval));
    3508             : 
    3509         234 :         ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), arg) {
    3510         167 :                 if (func && !Z_ISREF_P(arg) && ARG_SHOULD_BE_SENT_BY_REF(func, n)) {
    3511           5 :                         ZVAL_NEW_REF(params, arg);
    3512           5 :                         if (Z_REFCOUNTED_P(arg)) {
    3513             :                                 Z_ADDREF_P(arg);
    3514             :                         }
    3515             :                 } else {
    3516          77 :                         ZVAL_COPY(params, arg);
    3517             :                 }
    3518          82 :                 params++;
    3519          82 :                 n++;
    3520             :         } ZEND_HASH_FOREACH_END();
    3521             : 
    3522          70 :         return SUCCESS;
    3523             : }
    3524             : /* }}} */
    3525             : 
    3526          69 : ZEND_API int zend_fcall_info_args(zend_fcall_info *fci, zval *args) /* {{{ */
    3527             : {
    3528          69 :         return zend_fcall_info_args_ex(fci, NULL, args);
    3529             : }
    3530             : /* }}} */
    3531             : 
    3532           0 : ZEND_API int zend_fcall_info_argp(zend_fcall_info *fci, int argc, zval *argv) /* {{{ */
    3533             : {
    3534             :         int i;
    3535             : 
    3536           0 :         if (argc < 0) {
    3537           0 :                 return FAILURE;
    3538             :         }
    3539             : 
    3540           0 :         zend_fcall_info_args_clear(fci, !argc);
    3541             : 
    3542           0 :         if (argc) {
    3543           0 :                 fci->param_count = argc;
    3544           0 :                 fci->params = (zval *) erealloc(fci->params, fci->param_count * sizeof(zval));
    3545             : 
    3546           0 :                 for (i = 0; i < argc; ++i) {
    3547           0 :                         ZVAL_COPY(&fci->params[i], &argv[i]);
    3548             :                 }
    3549             :         }
    3550             : 
    3551           0 :         return SUCCESS;
    3552             : }
    3553             : /* }}} */
    3554             : 
    3555         250 : ZEND_API int zend_fcall_info_argv(zend_fcall_info *fci, int argc, va_list *argv) /* {{{ */
    3556             : {
    3557             :         int i;
    3558             :         zval *arg;
    3559             : 
    3560         250 :         if (argc < 0) {
    3561           0 :                 return FAILURE;
    3562             :         }
    3563             : 
    3564         250 :         zend_fcall_info_args_clear(fci, !argc);
    3565             : 
    3566         250 :         if (argc) {
    3567         127 :                 fci->param_count = argc;
    3568         127 :                 fci->params = (zval *) erealloc(fci->params, fci->param_count * sizeof(zval));
    3569             : 
    3570         381 :                 for (i = 0; i < argc; ++i) {
    3571         254 :                         arg = va_arg(*argv, zval *);
    3572         254 :                         ZVAL_COPY(&fci->params[i], arg);
    3573             :                 }
    3574             :         }
    3575             : 
    3576         250 :         return SUCCESS;
    3577             : }
    3578             : /* }}} */
    3579             : 
    3580         250 : ZEND_API int zend_fcall_info_argn(zend_fcall_info *fci, int argc, ...) /* {{{ */
    3581             : {
    3582             :         int ret;
    3583             :         va_list argv;
    3584             : 
    3585         250 :         va_start(argv, argc);
    3586         250 :         ret = zend_fcall_info_argv(fci, argc, &argv);
    3587         250 :         va_end(argv);
    3588             : 
    3589         250 :         return ret;
    3590             : }
    3591             : /* }}} */
    3592             : 
    3593         141 : ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *retval_ptr, zval *args) /* {{{ */
    3594             : {
    3595         141 :         zval retval, *org_params = NULL;
    3596         141 :         int result, org_count = 0;
    3597             : 
    3598         141 :         fci->retval = retval_ptr ? retval_ptr : &retval;
    3599         141 :         if (args) {
    3600           0 :                 zend_fcall_info_args_save(fci, &org_count, &org_params);
    3601           0 :                 zend_fcall_info_args(fci, args);
    3602             :         }
    3603         141 :         result = zend_call_function(fci, fcc);
    3604             : 
    3605         137 :         if (!retval_ptr && Z_TYPE(retval) != IS_UNDEF) {
    3606           0 :                 zval_ptr_dtor(&retval);
    3607             :         }
    3608         137 :         if (args) {
    3609           0 :                 zend_fcall_info_args_restore(fci, org_count, org_params);
    3610             :         }
    3611         137 :         return result;
    3612             : }
    3613             : /* }}} */
    3614             : 
    3615           1 : ZEND_API const char *zend_get_module_version(const char *module_name) /* {{{ */
    3616             : {
    3617             :         zend_string *lname;
    3618           1 :         size_t name_len = strlen(module_name);
    3619             :         zend_module_entry *module;
    3620             : 
    3621           1 :         lname = zend_string_alloc(name_len, 0);
    3622           1 :         zend_str_tolower_copy(lname->val, module_name, name_len);
    3623           1 :         module = zend_hash_find_ptr(&module_registry, lname);
    3624             :         zend_string_free(lname);
    3625           1 :         return module ? module->version : NULL;
    3626             : }
    3627             : /* }}} */
    3628             : 
    3629     1529313 : ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment) /* {{{ */
    3630             : {
    3631             :         zend_property_info *property_info, *property_info_ptr;
    3632             : 
    3633     1529313 :         if (ce->type == ZEND_INTERNAL_CLASS) {
    3634     1526868 :                 property_info = pemalloc(sizeof(zend_property_info), 1);
    3635             :         } else {
    3636        2445 :                 property_info = zend_arena_alloc(&CG(arena), sizeof(zend_property_info));
    3637             :         }
    3638             : 
    3639     1529313 :         if (Z_CONSTANT_P(property)) {
    3640          67 :                 ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
    3641             :         }
    3642     1529313 :         if (!(access_type & ZEND_ACC_PPP_MASK)) {
    3643       41902 :                 access_type |= ZEND_ACC_PUBLIC;
    3644             :         }
    3645     1529313 :         if (access_type & ZEND_ACC_STATIC) {
    3646         822 :                 if ((property_info_ptr = zend_hash_find_ptr(&ce->properties_info, name)) != NULL &&
    3647           0 :                     (property_info_ptr->flags & ZEND_ACC_STATIC) != 0) {
    3648           0 :                         property_info->offset = property_info_ptr->offset;
    3649           0 :                         zval_ptr_dtor(&ce->default_static_members_table[property_info->offset]);
    3650           0 :                         zend_hash_del(&ce->properties_info, name);
    3651             :                 } else {
    3652         411 :                         property_info->offset = ce->default_static_members_count++;
    3653         822 :                         ce->default_static_members_table = perealloc(ce->default_static_members_table, sizeof(zval) * ce->default_static_members_count, ce->type == ZEND_INTERNAL_CLASS);
    3654             :                 }
    3655         411 :                 ZVAL_COPY_VALUE(&ce->default_static_members_table[property_info->offset], property);
    3656         411 :                 if (ce->type == ZEND_USER_CLASS) {
    3657         411 :                         ce->static_members_table = ce->default_static_members_table;
    3658             :                 }
    3659             :         } else {
    3660     3225132 :                 if ((property_info_ptr = zend_hash_find_ptr(&ce->properties_info, name)) != NULL &&
    3661       83664 :                     (property_info_ptr->flags & ZEND_ACC_STATIC) == 0) {
    3662       83664 :                         property_info->offset = property_info_ptr->offset;
    3663       83664 :                         zval_ptr_dtor(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]);
    3664       83664 :                         zend_hash_del(&ce->properties_info, name);
    3665             :                 } else {
    3666     1445238 :                         property_info->offset = OBJ_PROP_TO_OFFSET(ce->default_properties_count);
    3667     1445238 :                         ce->default_properties_count++;
    3668     2890476 :                         ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(zval) * ce->default_properties_count, ce->type == ZEND_INTERNAL_CLASS);
    3669             :                 }
    3670     1528902 :                 ZVAL_COPY_VALUE(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)], property);
    3671             :         }
    3672     1529313 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    3673     1526868 :                 switch(Z_TYPE_P(property)) {
    3674             :                         case IS_ARRAY:
    3675             :                         case IS_OBJECT:
    3676             :                         case IS_RESOURCE:
    3677           0 :                                 zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
    3678             :                                 break;
    3679             :                         default:
    3680             :                                 break;
    3681             :                 }
    3682             :         }
    3683     1529313 :         switch (access_type & ZEND_ACC_PPP_MASK) {
    3684             :                 case ZEND_ACC_PRIVATE: {
    3685       63552 :                                 property_info->name = zend_mangle_property_name(ce->name->val, ce->name->len, name->val, name->len, ce->type & ZEND_INTERNAL_CLASS);
    3686             :                         }
    3687       63552 :                         break;
    3688             :                 case ZEND_ACC_PROTECTED: {
    3689      146797 :                                 property_info->name = zend_mangle_property_name("*", 1, name->val, name->len, ce->type & ZEND_INTERNAL_CLASS);
    3690             :                         }
    3691      146797 :                         break;
    3692             :                 case ZEND_ACC_PUBLIC:
    3693     1318964 :                         property_info->name = zend_string_copy(name);
    3694             :                         break;
    3695             :         }
    3696             : 
    3697     1529313 :         property_info->name = zend_new_interned_string(property_info->name);
    3698     1529313 :         property_info->flags = access_type;
    3699     1529313 :         property_info->doc_comment = doc_comment;
    3700     1529313 :         property_info->ce = ce;
    3701     1529313 :         zend_hash_update_ptr(&ce->properties_info, name, property_info);
    3702             : 
    3703     1529313 :         return SUCCESS;
    3704             : }
    3705             : /* }}} */
    3706             : 
    3707     1526868 : ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type) /* {{{ */
    3708             : {
    3709     3053736 :         zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS);
    3710     1526868 :         int ret = zend_declare_property_ex(ce, key, property, access_type, NULL);
    3711             :         zend_string_release(key);
    3712     1526868 :         return ret;
    3713             : }
    3714             : /* }}} */
    3715             : 
    3716     1066716 : ZEND_API int zend_declare_property_null(zend_class_entry *ce, const char *name, size_t name_length, int access_type) /* {{{ */
    3717             : {
    3718             :         zval property;
    3719             : 
    3720     1066716 :         ZVAL_NULL(&property);
    3721     1066716 :         return zend_declare_property(ce, name, name_length, &property, access_type);
    3722             : }
    3723             : /* }}} */
    3724             : 
    3725           0 : ZEND_API int zend_declare_property_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type) /* {{{ */
    3726             : {
    3727             :         zval property;
    3728             : 
    3729           0 :         ZVAL_BOOL(&property, value);
    3730           0 :         return zend_declare_property(ce, name, name_length, &property, access_type);
    3731             : }
    3732             : /* }}} */
    3733             : 
    3734       83664 : ZEND_API int zend_declare_property_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type) /* {{{ */
    3735             : {
    3736             :         zval property;
    3737             : 
    3738       83664 :         ZVAL_LONG(&property, value);
    3739       83664 :         return zend_declare_property(ce, name, name_length, &property, access_type);
    3740             : }
    3741             : /* }}} */
    3742             : 
    3743           0 : ZEND_API int zend_declare_property_double(zend_class_entry *ce, const char *name, size_t name_length, double value, int access_type) /* {{{ */
    3744             : {
    3745             :         zval property;
    3746             : 
    3747           0 :         ZVAL_DOUBLE(&property, value);
    3748           0 :         return zend_declare_property(ce, name, name_length, &property, access_type);
    3749             : }
    3750             : /* }}} */
    3751             : 
    3752      376488 : ZEND_API int zend_declare_property_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value, int access_type) /* {{{ */
    3753             : {
    3754             :         zval property;
    3755             : 
    3756      752976 :         ZVAL_NEW_STR(&property, zend_string_init(value, strlen(value), ce->type & ZEND_INTERNAL_CLASS));
    3757      376488 :         return zend_declare_property(ce, name, name_length, &property, access_type);
    3758             : }
    3759             : /* }}} */
    3760             : 
    3761           0 : ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_len, int access_type) /* {{{ */
    3762             : {
    3763             :         zval property;
    3764             : 
    3765           0 :         ZVAL_NEW_STR(&property, zend_string_init(value, value_len, ce->type & ZEND_INTERNAL_CLASS));
    3766           0 :         return zend_declare_property(ce, name, name_length, &property, access_type);
    3767             : }
    3768             : /* }}} */
    3769             : 
    3770    22191876 : ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value) /* {{{ */
    3771             : {
    3772    22191876 :         if (Z_CONSTANT_P(value)) {
    3773           0 :                 ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
    3774             :         }
    3775    22191876 :         return zend_hash_str_update(&ce->constants_table, name, name_length, value) ?
    3776             :                 SUCCESS : FAILURE;
    3777             : }
    3778             : /* }}} */
    3779             : 
    3780       20916 : ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, const char *name, size_t name_length) /* {{{ */
    3781             : {
    3782             :         zval constant;
    3783             : 
    3784       20916 :         ZVAL_NULL(&constant);
    3785       20916 :         return zend_declare_class_constant(ce, name, name_length, &constant);
    3786             : }
    3787             : /* }}} */
    3788             : 
    3789    21731724 : ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value) /* {{{ */
    3790             : {
    3791             :         zval constant;
    3792             : 
    3793    21731724 :         ZVAL_LONG(&constant, value);
    3794    21731724 :         return zend_declare_class_constant(ce, name, name_length, &constant);
    3795             : }
    3796             : /* }}} */
    3797             : 
    3798           0 : ZEND_API int zend_declare_class_constant_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_bool value) /* {{{ */
    3799             : {
    3800             :         zval constant;
    3801             : 
    3802           0 :         ZVAL_BOOL(&constant, value);
    3803           0 :         return zend_declare_class_constant(ce, name, name_length, &constant);
    3804             : }
    3805             : /* }}} */
    3806             : 
    3807           0 : ZEND_API int zend_declare_class_constant_double(zend_class_entry *ce, const char *name, size_t name_length, double value) /* {{{ */
    3808             : {
    3809             :         zval constant;
    3810             : 
    3811           0 :         ZVAL_DOUBLE(&constant, value);
    3812           0 :         return zend_declare_class_constant(ce, name, name_length, &constant);
    3813             : }
    3814             : /* }}} */
    3815             : 
    3816      439236 : 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) /* {{{ */
    3817             : {
    3818             :         zval constant;
    3819             : 
    3820      878472 :         ZVAL_NEW_STR(&constant, zend_string_init(value, value_length, ce->type & ZEND_INTERNAL_CLASS));
    3821      439236 :         return zend_declare_class_constant(ce, name, name_length, &constant);
    3822             : }
    3823             : /* }}} */
    3824             : 
    3825      167328 : ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value) /* {{{ */
    3826             : {
    3827      167328 :         return zend_declare_class_constant_stringl(ce, name, name_length, value, strlen(value));
    3828             : }
    3829             : /* }}} */
    3830             : 
    3831         524 : ZEND_API void zend_update_property_ex(zend_class_entry *scope, zval *object, zend_string *name, zval *value) /* {{{ */
    3832             : {
    3833             :         zval property;
    3834         524 :         zend_class_entry *old_scope = EG(scope);
    3835             : 
    3836         524 :         EG(scope) = scope;
    3837             : 
    3838         524 :         if (!Z_OBJ_HT_P(object)->write_property) {
    3839           0 :                 zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, Z_OBJCE_P(object)->name->val);
    3840             :         }
    3841         524 :         ZVAL_STR(&property, name);
    3842         524 :         Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL);
    3843             : 
    3844         524 :         EG(scope) = old_scope;
    3845         524 : }
    3846             : /* }}} */
    3847             : 
    3848       13521 : ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zval *value) /* {{{ */
    3849             : {
    3850             :         zval property;
    3851       13521 :         zend_class_entry *old_scope = EG(scope);
    3852             : 
    3853       13521 :         EG(scope) = scope;
    3854             : 
    3855       13521 :         if (!Z_OBJ_HT_P(object)->write_property) {
    3856           0 :                 zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, Z_OBJCE_P(object)->name->val);
    3857             :         }
    3858       27042 :         ZVAL_STRINGL(&property, name, name_length);
    3859       13521 :         Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL);
    3860       13521 :         zval_ptr_dtor(&property);
    3861             : 
    3862       13521 :         EG(scope) = old_scope;
    3863       13521 : }
    3864             : /* }}} */
    3865             : 
    3866           0 : ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, size_t name_length) /* {{{ */
    3867             : {
    3868             :         zval tmp;
    3869             : 
    3870           0 :         ZVAL_NULL(&tmp);
    3871           0 :         zend_update_property(scope, object, name, name_length, &tmp);
    3872           0 : }
    3873             : /* }}} */
    3874             : 
    3875           0 : ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value) /* {{{ */
    3876             : {
    3877             :         zval tmp;
    3878             : 
    3879           0 :         ZVAL_BOOL(&tmp, value);
    3880           0 :         zend_update_property(scope, object, name, name_length, &tmp);
    3881           0 : }
    3882             : /* }}} */
    3883             : 
    3884        3901 : ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value) /* {{{ */
    3885             : {
    3886             :         zval tmp;
    3887             : 
    3888        3901 :         ZVAL_LONG(&tmp, value);
    3889        3901 :         zend_update_property(scope, object, name, name_length, &tmp);
    3890        3901 : }
    3891             : /* }}} */
    3892             : 
    3893           0 : ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, const char *name, size_t name_length, double value) /* {{{ */
    3894             : {
    3895             :         zval tmp;
    3896             : 
    3897           0 :         ZVAL_DOUBLE(&tmp, value);
    3898           0 :         zend_update_property(scope, object, name, name_length, &tmp);
    3899           0 : }
    3900             : /* }}} */
    3901             : 
    3902         780 : ZEND_API void zend_update_property_str(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_string *value) /* {{{ */
    3903             : {
    3904             :         zval tmp;
    3905             : 
    3906         780 :         ZVAL_STR(&tmp, value);
    3907         780 :         zend_update_property(scope, object, name, name_length, &tmp);
    3908         780 : }
    3909             : /* }}} */
    3910             : 
    3911        5873 : ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value) /* {{{ */
    3912             : {
    3913             :         zval tmp;
    3914             : 
    3915       11746 :         ZVAL_STRING(&tmp, value);
    3916             :         Z_SET_REFCOUNT(tmp, 0);
    3917        5873 :         zend_update_property(scope, object, name, name_length, &tmp);
    3918        5873 : }
    3919             : /* }}} */
    3920             : 
    3921          21 : ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value, size_t value_len) /* {{{ */
    3922             : {
    3923             :         zval tmp;
    3924             : 
    3925          42 :         ZVAL_STRINGL(&tmp, value, value_len);
    3926             :         Z_SET_REFCOUNT(tmp, 0);
    3927          21 :         zend_update_property(scope, object, name, name_length, &tmp);
    3928          21 : }
    3929             : /* }}} */
    3930             : 
    3931           0 : ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, size_t name_length, zval *value) /* {{{ */
    3932             : {
    3933             :         zval *property;
    3934           0 :         zend_class_entry *old_scope = EG(scope);
    3935           0 :         zend_string *key = zend_string_init(name, name_length, 0);
    3936             : 
    3937           0 :         EG(scope) = scope;
    3938           0 :         property = zend_std_get_static_property(scope, key, 0);
    3939           0 :         EG(scope) = old_scope;
    3940             :         zend_string_free(key);
    3941           0 :         if (!property) {
    3942           0 :                 return FAILURE;
    3943             :         } else {
    3944           0 :                 if (property != value) {
    3945           0 :                         if (Z_ISREF_P(property)) {
    3946             :                                 zval_dtor(property);
    3947           0 :                                 ZVAL_COPY_VALUE(property, value);
    3948           0 :                                 if (Z_REFCOUNT_P(value) > 0) {
    3949             :                                         zval_opt_copy_ctor(property);
    3950             :                                 }
    3951             :                         } else {
    3952             :                                 zval garbage;
    3953             : 
    3954           0 :                                 ZVAL_COPY_VALUE(&garbage, property);
    3955           0 :                                 if (Z_REFCOUNTED_P(value)) {
    3956             :                                         Z_ADDREF_P(value);
    3957           0 :                                         if (Z_ISREF_P(value)) {
    3958           0 :                                                 SEPARATE_ZVAL(value);
    3959             :                                         }
    3960             :                                 }
    3961           0 :                                 ZVAL_COPY_VALUE(property, value);
    3962           0 :                                 zval_ptr_dtor(&garbage);
    3963             :                         }
    3964             :                 }
    3965           0 :                 return SUCCESS;
    3966             :         }
    3967             : }
    3968             : /* }}} */
    3969             : 
    3970           0 : ZEND_API int zend_update_static_property_null(zend_class_entry *scope, const char *name, size_t name_length) /* {{{ */
    3971             : {
    3972             :         zval tmp;
    3973             : 
    3974           0 :         ZVAL_NULL(&tmp);
    3975           0 :         return zend_update_static_property(scope, name, name_length, &tmp);
    3976             : }
    3977             : /* }}} */
    3978             : 
    3979           0 : ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, const char *name, size_t name_length, zend_long value) /* {{{ */
    3980             : {
    3981             :         zval tmp;
    3982             : 
    3983           0 :         ZVAL_BOOL(&tmp, value);
    3984           0 :         return zend_update_static_property(scope, name, name_length, &tmp);
    3985             : }
    3986             : /* }}} */
    3987             : 
    3988           0 : ZEND_API int zend_update_static_property_long(zend_class_entry *scope, const char *name, size_t name_length, zend_long value) /* {{{ */
    3989             : {
    3990             :         zval tmp;
    3991             : 
    3992           0 :         ZVAL_LONG(&tmp, value);
    3993           0 :         return zend_update_static_property(scope, name, name_length, &tmp);
    3994             : }
    3995             : /* }}} */
    3996             : 
    3997           0 : ZEND_API int zend_update_static_property_double(zend_class_entry *scope, const char *name, size_t name_length, double value) /* {{{ */
    3998             : {
    3999             :         zval tmp;
    4000             : 
    4001           0 :         ZVAL_DOUBLE(&tmp, value);
    4002           0 :         return zend_update_static_property(scope, name, name_length, &tmp);
    4003             : }
    4004             : /* }}} */
    4005             : 
    4006           0 : ZEND_API int zend_update_static_property_string(zend_class_entry *scope, const char *name, size_t name_length, const char *value) /* {{{ */
    4007             : {
    4008             :         zval tmp;
    4009             : 
    4010           0 :         ZVAL_STRING(&tmp, value);
    4011             :         Z_SET_REFCOUNT(tmp, 0);
    4012           0 :         return zend_update_static_property(scope, name, name_length, &tmp);
    4013             : }
    4014             : /* }}} */
    4015             : 
    4016           0 : ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const char *name, size_t name_length, const char *value, size_t value_len) /* {{{ */
    4017             : {
    4018             :         zval tmp;
    4019             : 
    4020           0 :         ZVAL_STRINGL(&tmp, value, value_len);
    4021             :         Z_SET_REFCOUNT(tmp, 0);
    4022           0 :         return zend_update_static_property(scope, name, name_length, &tmp);
    4023             : }
    4024             : /* }}} */
    4025             : 
    4026        5937 : ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent, zval *rv) /* {{{ */
    4027             : {
    4028             :         zval property, *value;
    4029        5937 :         zend_class_entry *old_scope = EG(scope);
    4030             : 
    4031        5937 :         EG(scope) = scope;
    4032             : 
    4033        5937 :         if (!Z_OBJ_HT_P(object)->read_property) {
    4034           0 :                 zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be read", name, Z_OBJCE_P(object)->name->val);
    4035             :         }
    4036             : 
    4037       11874 :         ZVAL_STRINGL(&property, name, name_length);
    4038        5937 :         value = Z_OBJ_HT_P(object)->read_property(object, &property, silent?BP_VAR_IS:BP_VAR_R, NULL, rv);
    4039        5937 :         zval_ptr_dtor(&property);
    4040             : 
    4041        5937 :         EG(scope) = old_scope;
    4042        5937 :         return value;
    4043             : }
    4044             : /* }}} */
    4045             : 
    4046           0 : ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent) /* {{{ */
    4047             : {
    4048             :         zval *property;
    4049           0 :         zend_class_entry *old_scope = EG(scope);
    4050           0 :         zend_string *key = zend_string_init(name, name_length, 0);
    4051             : 
    4052           0 :         EG(scope) = scope;
    4053           0 :         property = zend_std_get_static_property(scope, key, silent);
    4054           0 :         EG(scope) = old_scope;
    4055             :         zend_string_free(key);
    4056             : 
    4057           0 :         return property;
    4058             : }
    4059             : /* }}} */
    4060             : 
    4061      191773 : ZEND_API void zend_save_error_handling(zend_error_handling *current) /* {{{ */
    4062             : {
    4063      191773 :         current->handling = EG(error_handling);
    4064      191773 :         current->exception = EG(exception_class);
    4065      191773 :         ZVAL_COPY(&current->user_handler, &EG(user_error_handler));
    4066      191773 : }
    4067             : /* }}} */
    4068             : 
    4069      191773 : ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current) /* {{{ */
    4070             : {
    4071      191773 :         if (current) {
    4072      191773 :                 zend_save_error_handling(current);
    4073      383546 :                 if (error_handling != EH_NORMAL && Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
    4074           6 :                         zval_ptr_dtor(&EG(user_error_handler));
    4075           6 :                         ZVAL_UNDEF(&EG(user_error_handler));
    4076             :                 }
    4077             :         }
    4078      191773 :         EG(error_handling) = error_handling;
    4079      191773 :         EG(exception_class) = error_handling == EH_THROW ? exception_class : NULL;
    4080      191773 : }
    4081             : /* }}} */
    4082             : 
    4083           6 : static int same_zval(zval *zv1, zval *zv2)  /* {{{ */
    4084             : {
    4085           6 :         if (Z_TYPE_P(zv1) != Z_TYPE_P(zv2)) {
    4086           6 :                 return 0;
    4087             :         }
    4088           0 :         switch (Z_TYPE_P(zv1)) {
    4089             :                 case IS_UNDEF:
    4090             :                 case IS_NULL:
    4091             :                 case IS_FALSE:
    4092             :                 case IS_TRUE:
    4093           0 :                         return 1;
    4094             :                 case IS_LONG:
    4095           0 :                         return Z_LVAL_P(zv1) == Z_LVAL_P(zv2);
    4096             :                 case IS_DOUBLE:
    4097           0 :                         return Z_LVAL_P(zv1) == Z_LVAL_P(zv2);
    4098             :                 case IS_STRING:
    4099             :                 case IS_ARRAY:
    4100             :                 case IS_OBJECT:
    4101             :                 case IS_RESOURCE:
    4102           0 :                         return Z_COUNTED_P(zv1) == Z_COUNTED_P(zv2);
    4103             :                 default:
    4104           0 :                         return 0;
    4105             :         }
    4106             : }
    4107             : /* }}} */
    4108             : 
    4109      191773 : ZEND_API void zend_restore_error_handling(zend_error_handling *saved) /* {{{ */
    4110             : {
    4111      191773 :         EG(error_handling) = saved->handling;
    4112      191773 :         EG(exception_class) = saved->handling == EH_THROW ? saved->exception : NULL;
    4113      383558 :         if (Z_TYPE(saved->user_handler) != IS_UNDEF
    4114           6 :                 && !same_zval(&saved->user_handler, &EG(user_error_handler))) {
    4115           6 :                 zval_ptr_dtor(&EG(user_error_handler));
    4116           6 :                 ZVAL_COPY_VALUE(&EG(user_error_handler), &saved->user_handler);
    4117      383534 :         } else if (Z_TYPE(saved->user_handler)) {
    4118           0 :                 zval_ptr_dtor(&saved->user_handler);
    4119             :         }
    4120      191773 :         ZVAL_UNDEF(&saved->user_handler);
    4121      191773 : }
    4122             : /* }}} */
    4123             : 
    4124           9 : ZEND_API zend_string* zend_find_alias_name(zend_class_entry *ce, zend_string *name) /* {{{ */
    4125             : {
    4126             :         zend_trait_alias *alias, **alias_ptr;
    4127             : 
    4128           9 :         if ((alias_ptr = ce->trait_aliases)) {
    4129           8 :                 alias = *alias_ptr;
    4130          16 :                 while (alias) {
    4131          16 :                         if (alias->alias->len == name->len &&
    4132           8 :                                 !strncasecmp(name->val, alias->alias->val, alias->alias->len)) {
    4133           8 :                                 return alias->alias;
    4134             :                         }
    4135           0 :                         alias_ptr++;
    4136           0 :                         alias = *alias_ptr;
    4137             :                 }
    4138             :         }
    4139             : 
    4140           1 :         return name;
    4141             : }
    4142             : /* }}} */
    4143             : 
    4144          11 : ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_function *f) /* {{{ */
    4145             : {
    4146             :         zend_function *func;
    4147             :         HashTable *function_table;
    4148             :         zend_string *name;
    4149             : 
    4150          55 :         if (f->common.type != ZEND_USER_FUNCTION ||
    4151          22 :             (f->op_array.refcount && *(f->op_array.refcount) < 2) ||
    4152          11 :             !f->common.scope ||
    4153          11 :             !f->common.scope->trait_aliases) {
    4154           0 :                 return f->common.function_name;
    4155             :         }
    4156             : 
    4157          11 :         function_table = &ce->function_table;
    4158          32 :         ZEND_HASH_FOREACH_STR_KEY_PTR(function_table, name, func) {
    4159          16 :                 if (func == f) {
    4160          11 :                         if (!name) {
    4161           0 :                                 return f->common.function_name;
    4162             :                         }
    4163          16 :                         if (name->len == f->common.function_name->len &&
    4164           5 :                             !strncasecmp(name->val, f->common.function_name->val, f->common.function_name->len)) {
    4165           5 :                                 return f->common.function_name;
    4166             :                         }
    4167           6 :                         return zend_find_alias_name(f->common.scope, name);
    4168             :                 }
    4169             :         } ZEND_HASH_FOREACH_END();
    4170           0 :         return f->common.function_name;
    4171             : }
    4172             : /* }}} */
    4173             : 
    4174          12 : ZEND_API const char *zend_get_object_type(const zend_class_entry *ce) /* {{{ */
    4175             : {
    4176          12 :         if(ce->ce_flags & ZEND_ACC_TRAIT) {
    4177           3 :                 return "trait";
    4178           9 :         } else if (ce->ce_flags & ZEND_ACC_INTERFACE) {
    4179           4 :                 return "interface";
    4180             :         } else {
    4181           5 :                 return "class";
    4182             :         }
    4183             : }
    4184             : /* }}} */
    4185             : 
    4186             : /*
    4187             :  * Local variables:
    4188             :  * tab-width: 4
    4189             :  * c-basic-offset: 4
    4190             :  * indent-tabs-mode: t
    4191             :  * End:
    4192             :  */

Generated by: LCOV version 1.10

Generated at Thu, 21 May 2015 19:58:53 +0000 (17 hours ago)

Copyright © 2005-2015 The PHP Group
All rights reserved.