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_builtin_functions.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 831 918 90.5 %
Date: 2014-04-18 Functions: 61 62 98.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2013 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             :    +----------------------------------------------------------------------+
      18             : */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #include "zend.h"
      23             : #include "zend_API.h"
      24             : #include "zend_builtin_functions.h"
      25             : #include "zend_constants.h"
      26             : #include "zend_ini.h"
      27             : #include "zend_exceptions.h"
      28             : #include "zend_extensions.h"
      29             : #include "zend_closures.h"
      30             : 
      31             : #undef ZEND_TEST_EXCEPTIONS
      32             : 
      33             : static ZEND_FUNCTION(zend_version);
      34             : static ZEND_FUNCTION(func_num_args);
      35             : static ZEND_FUNCTION(func_get_arg);
      36             : static ZEND_FUNCTION(func_get_args);
      37             : static ZEND_FUNCTION(strlen);
      38             : static ZEND_FUNCTION(strcmp);
      39             : static ZEND_FUNCTION(strncmp);
      40             : static ZEND_FUNCTION(strcasecmp);
      41             : static ZEND_FUNCTION(strncasecmp);
      42             : static ZEND_FUNCTION(each);
      43             : static ZEND_FUNCTION(error_reporting);
      44             : static ZEND_FUNCTION(define);
      45             : static ZEND_FUNCTION(defined);
      46             : static ZEND_FUNCTION(get_class);
      47             : static ZEND_FUNCTION(get_called_class);
      48             : static ZEND_FUNCTION(get_parent_class);
      49             : static ZEND_FUNCTION(method_exists);
      50             : static ZEND_FUNCTION(property_exists);
      51             : static ZEND_FUNCTION(class_exists);
      52             : static ZEND_FUNCTION(interface_exists);
      53             : static ZEND_FUNCTION(function_exists);
      54             : static ZEND_FUNCTION(class_alias);
      55             : #if ZEND_DEBUG
      56             : static ZEND_FUNCTION(leak);
      57             : #ifdef ZEND_TEST_EXCEPTIONS
      58             : static ZEND_FUNCTION(crash);
      59             : #endif
      60             : #endif
      61             : static ZEND_FUNCTION(get_included_files);
      62             : static ZEND_FUNCTION(is_subclass_of);
      63             : static ZEND_FUNCTION(is_a);
      64             : static ZEND_FUNCTION(get_class_vars);
      65             : static ZEND_FUNCTION(get_object_vars);
      66             : static ZEND_FUNCTION(get_class_methods);
      67             : static ZEND_FUNCTION(trigger_error);
      68             : static ZEND_FUNCTION(set_error_handler);
      69             : static ZEND_FUNCTION(restore_error_handler);
      70             : static ZEND_FUNCTION(set_exception_handler);
      71             : static ZEND_FUNCTION(restore_exception_handler);
      72             : static ZEND_FUNCTION(get_declared_classes);
      73             : static ZEND_FUNCTION(get_declared_interfaces);
      74             : static ZEND_FUNCTION(get_defined_functions);
      75             : static ZEND_FUNCTION(get_defined_vars);
      76             : static ZEND_FUNCTION(create_function);
      77             : static ZEND_FUNCTION(get_resource_type);
      78             : static ZEND_FUNCTION(get_loaded_extensions);
      79             : static ZEND_FUNCTION(extension_loaded);
      80             : static ZEND_FUNCTION(get_extension_funcs);
      81             : static ZEND_FUNCTION(get_defined_constants);
      82             : static ZEND_FUNCTION(debug_backtrace);
      83             : static ZEND_FUNCTION(debug_print_backtrace);
      84             : #if ZEND_DEBUG
      85             : static ZEND_FUNCTION(zend_test_func);
      86             : #ifdef ZTS
      87             : static ZEND_FUNCTION(zend_thread_id);
      88             : #endif
      89             : #endif
      90             : static ZEND_FUNCTION(gc_collect_cycles);
      91             : static ZEND_FUNCTION(gc_enabled);
      92             : static ZEND_FUNCTION(gc_enable);
      93             : static ZEND_FUNCTION(gc_disable);
      94             : 
      95             : /* {{{ arginfo */
      96             : ZEND_BEGIN_ARG_INFO(arginfo_zend__void, 0)
      97             : ZEND_END_ARG_INFO()
      98             : 
      99             : ZEND_BEGIN_ARG_INFO_EX(arginfo_func_get_arg, 0, 0, 1)
     100             :         ZEND_ARG_INFO(0, arg_num)
     101             : ZEND_END_ARG_INFO()
     102             : 
     103             : ZEND_BEGIN_ARG_INFO_EX(arginfo_strlen, 0, 0, 1)
     104             :         ZEND_ARG_INFO(0, str)
     105             : ZEND_END_ARG_INFO()
     106             : 
     107             : ZEND_BEGIN_ARG_INFO_EX(arginfo_strcmp, 0, 0, 2)
     108             :         ZEND_ARG_INFO(0, str1)
     109             :         ZEND_ARG_INFO(0, str2)
     110             : ZEND_END_ARG_INFO()
     111             : 
     112             : ZEND_BEGIN_ARG_INFO_EX(arginfo_strncmp, 0, 0, 3)
     113             :         ZEND_ARG_INFO(0, str1)
     114             :         ZEND_ARG_INFO(0, str2)
     115             :         ZEND_ARG_INFO(0, len)
     116             : ZEND_END_ARG_INFO()
     117             : 
     118             : ZEND_BEGIN_ARG_INFO_EX(arginfo_each, 0, 0, 1)
     119             :         ZEND_ARG_INFO(1, arr)
     120             : ZEND_END_ARG_INFO()
     121             : 
     122             : ZEND_BEGIN_ARG_INFO_EX(arginfo_error_reporting, 0, 0, 0)
     123             :         ZEND_ARG_INFO(0, new_error_level)
     124             : ZEND_END_ARG_INFO()
     125             : 
     126             : ZEND_BEGIN_ARG_INFO_EX(arginfo_define, 0, 0, 3)
     127             :         ZEND_ARG_INFO(0, constant_name)
     128             :         ZEND_ARG_INFO(0, value)
     129             :         ZEND_ARG_INFO(0, case_insensitive)
     130             : ZEND_END_ARG_INFO()
     131             : 
     132             : ZEND_BEGIN_ARG_INFO_EX(arginfo_defined, 0, 0, 1)
     133             :         ZEND_ARG_INFO(0, constant_name)
     134             : ZEND_END_ARG_INFO()
     135             : 
     136             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class, 0, 0, 0)
     137             :         ZEND_ARG_INFO(0, object)
     138             : ZEND_END_ARG_INFO()
     139             : 
     140             : ZEND_BEGIN_ARG_INFO_EX(arginfo_is_subclass_of, 0, 0, 2)
     141             :         ZEND_ARG_INFO(0, object)
     142             :         ZEND_ARG_INFO(0, class_name)
     143             : ZEND_END_ARG_INFO()
     144             : 
     145             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_vars, 0, 0, 1)
     146             :         ZEND_ARG_INFO(0, class_name)
     147             : ZEND_END_ARG_INFO()
     148             : 
     149             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_object_vars, 0, 0, 1)
     150             :         ZEND_ARG_INFO(0, obj)
     151             : ZEND_END_ARG_INFO()
     152             : 
     153             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_methods, 0, 0, 1)
     154             :         ZEND_ARG_INFO(0, class)
     155             : ZEND_END_ARG_INFO()
     156             : 
     157             : ZEND_BEGIN_ARG_INFO_EX(arginfo_method_exists, 0, 0, 2)
     158             :         ZEND_ARG_INFO(0, object)
     159             :         ZEND_ARG_INFO(0, method)
     160             : ZEND_END_ARG_INFO()
     161             : 
     162             : ZEND_BEGIN_ARG_INFO_EX(arginfo_property_exists, 0, 0, 2)
     163             :         ZEND_ARG_INFO(0, object_or_class)
     164             :         ZEND_ARG_INFO(0, property_name)
     165             : ZEND_END_ARG_INFO()
     166             : 
     167             : ZEND_BEGIN_ARG_INFO_EX(arginfo_class_exists, 0, 0, 1)
     168             :         ZEND_ARG_INFO(0, classname)
     169             :         ZEND_ARG_INFO(0, autoload)
     170             : ZEND_END_ARG_INFO()
     171             : 
     172             : ZEND_BEGIN_ARG_INFO_EX(arginfo_function_exists, 0, 0, 1)
     173             :         ZEND_ARG_INFO(0, function_name)
     174             : ZEND_END_ARG_INFO()
     175             : 
     176             : ZEND_BEGIN_ARG_INFO_EX(arginfo_class_alias, 0, 0, 2)
     177             :         ZEND_ARG_INFO(0, user_class_name)
     178             :         ZEND_ARG_INFO(0, alias_name)
     179             :         ZEND_ARG_INFO(0, autoload)
     180             : ZEND_END_ARG_INFO()
     181             : 
     182             : ZEND_BEGIN_ARG_INFO_EX(arginfo_trigger_error, 0, 0, 1)
     183             :         ZEND_ARG_INFO(0, message)
     184             :         ZEND_ARG_INFO(0, error_type)
     185             : ZEND_END_ARG_INFO()
     186             : 
     187             : ZEND_BEGIN_ARG_INFO_EX(arginfo_set_error_handler, 0, 0, 1)
     188             :         ZEND_ARG_INFO(0, error_handler)
     189             :         ZEND_ARG_INFO(0, error_types)
     190             : ZEND_END_ARG_INFO()
     191             : 
     192             : ZEND_BEGIN_ARG_INFO_EX(arginfo_set_exception_handler, 0, 0, 1)
     193             :         ZEND_ARG_INFO(0, exception_handler)
     194             : ZEND_END_ARG_INFO()
     195             : 
     196             : ZEND_BEGIN_ARG_INFO_EX(arginfo_create_function, 0, 0, 2)
     197             :         ZEND_ARG_INFO(0, args)
     198             :         ZEND_ARG_INFO(0, code)
     199             : ZEND_END_ARG_INFO()
     200             : 
     201             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_resource_type, 0, 0, 1)
     202             :         ZEND_ARG_INFO(0, res)
     203             : ZEND_END_ARG_INFO()
     204             : 
     205             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_loaded_extensions, 0, 0, 0)
     206             :         ZEND_ARG_INFO(0, zend_extensions)
     207             : ZEND_END_ARG_INFO()
     208             : 
     209             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_defined_constants, 0, 0, 0)
     210             :         ZEND_ARG_INFO(0, categorize)
     211             : ZEND_END_ARG_INFO()
     212             : 
     213             : ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_backtrace, 0, 0, 0)
     214             :         ZEND_ARG_INFO(0, options)
     215             : ZEND_END_ARG_INFO()
     216             : 
     217             : ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1)
     218             :         ZEND_ARG_INFO(0, extension_name)
     219             : ZEND_END_ARG_INFO()
     220             : /* }}} */
     221             : 
     222             : static const zend_function_entry builtin_functions[] = { /* {{{ */
     223             :         ZEND_FE(zend_version,           arginfo_zend__void)
     224             :         ZEND_FE(func_num_args,          arginfo_zend__void)
     225             :         ZEND_FE(func_get_arg,           arginfo_func_get_arg)
     226             :         ZEND_FE(func_get_args,          arginfo_zend__void)
     227             :         ZEND_FE(strlen,                         arginfo_strlen)
     228             :         ZEND_FE(strcmp,                         arginfo_strcmp)
     229             :         ZEND_FE(strncmp,                        arginfo_strncmp)
     230             :         ZEND_FE(strcasecmp,                     arginfo_strcmp)
     231             :         ZEND_FE(strncasecmp,            arginfo_strncmp)
     232             :         ZEND_FE(each,                           arginfo_each)
     233             :         ZEND_FE(error_reporting,        arginfo_error_reporting)
     234             :         ZEND_FE(define,                         arginfo_define)
     235             :         ZEND_FE(defined,                        arginfo_defined)
     236             :         ZEND_FE(get_class,                      arginfo_get_class)
     237             :         ZEND_FE(get_called_class,       arginfo_zend__void)
     238             :         ZEND_FE(get_parent_class,       arginfo_get_class)
     239             :         ZEND_FE(method_exists,          arginfo_method_exists)
     240             :         ZEND_FE(property_exists,        arginfo_property_exists)
     241             :         ZEND_FE(class_exists,           arginfo_class_exists)
     242             :         ZEND_FE(interface_exists,       arginfo_class_exists)
     243             :         ZEND_FE(function_exists,        arginfo_function_exists)
     244             :         ZEND_FE(class_alias,            arginfo_class_alias)
     245             : #if ZEND_DEBUG
     246             :         ZEND_FE(leak,                           NULL)
     247             : #ifdef ZEND_TEST_EXCEPTIONS
     248             :         ZEND_FE(crash,                          NULL)
     249             : #endif
     250             : #endif
     251             :         ZEND_FE(get_included_files,     arginfo_zend__void)
     252             :         ZEND_FALIAS(get_required_files, get_included_files,             arginfo_zend__void)
     253             :         ZEND_FE(is_subclass_of,         arginfo_is_subclass_of)
     254             :         ZEND_FE(is_a,                           arginfo_is_subclass_of)
     255             :         ZEND_FE(get_class_vars,         arginfo_get_class_vars)
     256             :         ZEND_FE(get_object_vars,        arginfo_get_object_vars)
     257             :         ZEND_FE(get_class_methods,      arginfo_get_class_methods)
     258             :         ZEND_FE(trigger_error,          arginfo_trigger_error)
     259             :         ZEND_FALIAS(user_error,         trigger_error,          arginfo_trigger_error)
     260             :         ZEND_FE(set_error_handler,                      arginfo_set_error_handler)
     261             :         ZEND_FE(restore_error_handler,          arginfo_zend__void)
     262             :         ZEND_FE(set_exception_handler,          arginfo_set_exception_handler)
     263             :         ZEND_FE(restore_exception_handler,      arginfo_zend__void)
     264             :         ZEND_FE(get_declared_classes,           arginfo_zend__void)
     265             :         ZEND_FE(get_declared_interfaces,        arginfo_zend__void)
     266             :         ZEND_FE(get_defined_functions,          arginfo_zend__void)
     267             :         ZEND_FE(get_defined_vars,                       arginfo_zend__void)
     268             :         ZEND_FE(create_function,                        arginfo_create_function)
     269             :         ZEND_FE(get_resource_type,                      arginfo_get_resource_type)
     270             :         ZEND_FE(get_loaded_extensions,          arginfo_get_loaded_extensions)
     271             :         ZEND_FE(extension_loaded,                       arginfo_extension_loaded)
     272             :         ZEND_FE(get_extension_funcs,            arginfo_extension_loaded)
     273             :         ZEND_FE(get_defined_constants,          arginfo_get_defined_constants)
     274             :         ZEND_FE(debug_backtrace,                        arginfo_debug_backtrace)
     275             :         ZEND_FE(debug_print_backtrace,          arginfo_debug_backtrace)
     276             : #if ZEND_DEBUG
     277             :         ZEND_FE(zend_test_func,         NULL)
     278             : #ifdef ZTS
     279             :         ZEND_FE(zend_thread_id,         NULL)
     280             : #endif
     281             : #endif
     282             :         ZEND_FE(gc_collect_cycles,      arginfo_zend__void)
     283             :         ZEND_FE(gc_enabled,             arginfo_zend__void)
     284             :         ZEND_FE(gc_enable,                      arginfo_zend__void)
     285             :         ZEND_FE(gc_disable,             arginfo_zend__void)
     286             :         ZEND_FE_END
     287             : };
     288             : /* }}} */
     289             : 
     290       19341 : ZEND_MINIT_FUNCTION(core) { /* {{{ */
     291             :         zend_class_entry class_entry;
     292             : 
     293       19341 :         INIT_CLASS_ENTRY(class_entry, "stdClass", NULL);
     294       19341 :         zend_standard_class_def = zend_register_internal_class(&class_entry TSRMLS_CC);
     295             : 
     296       19341 :         zend_register_default_classes(TSRMLS_C);
     297             : 
     298       19341 :         return SUCCESS;
     299             : }
     300             : /* }}} */
     301             : 
     302             : zend_module_entry zend_builtin_module = { /* {{{ */
     303             :     STANDARD_MODULE_HEADER,
     304             :         "Core",
     305             :         builtin_functions,
     306             :         ZEND_MINIT(core),
     307             :         NULL,
     308             :         NULL,
     309             :         NULL,
     310             :         NULL,
     311             :         ZEND_VERSION,
     312             :         STANDARD_MODULE_PROPERTIES
     313             : };
     314             : /* }}} */
     315             : 
     316       19341 : int zend_startup_builtin_functions(TSRMLS_D) /* {{{ */
     317             : {
     318       19341 :         zend_builtin_module.module_number = 0;
     319       19341 :         zend_builtin_module.type = MODULE_PERSISTENT;
     320       19341 :         return (EG(current_module) = zend_register_module_ex(&zend_builtin_module TSRMLS_CC)) == NULL ? FAILURE : SUCCESS;
     321             : }
     322             : /* }}} */
     323             : 
     324             : /* {{{ proto string zend_version(void)
     325             :    Get the version of the Zend Engine */
     326         136 : ZEND_FUNCTION(zend_version)
     327             : {
     328         136 :         RETURN_STRINGL(ZEND_VERSION, sizeof(ZEND_VERSION)-1, 1);
     329             : }
     330             : /* }}} */
     331             : 
     332             : /* {{{ proto int gc_collect_cycles(void)
     333             :    Forces collection of any existing garbage cycles.
     334             :    Returns number of freed zvals */
     335          42 : ZEND_FUNCTION(gc_collect_cycles)
     336             : {
     337          42 :         RETURN_LONG(gc_collect_cycles(TSRMLS_C));
     338             : }
     339             : /* }}} */
     340             : 
     341             : /* {{{ proto void gc_enabled(void)
     342             :    Returns status of the circular reference collector */
     343           6 : ZEND_FUNCTION(gc_enabled)
     344             : {
     345           6 :         RETURN_BOOL(GC_G(gc_enabled));
     346             : }
     347             : /* }}} */
     348             : 
     349             : /* {{{ proto void gc_enable(void)
     350             :    Activates the circular reference collector */
     351           5 : ZEND_FUNCTION(gc_enable)
     352             : {
     353           5 :         zend_alter_ini_entry("zend.enable_gc", sizeof("zend.enable_gc"), "1", sizeof("1")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
     354           5 : }
     355             : /* }}} */
     356             : 
     357             : /* {{{ proto void gc_disable(void)
     358             :    Deactivates the circular reference collector */
     359           2 : ZEND_FUNCTION(gc_disable)
     360             : {
     361           2 :         zend_alter_ini_entry("zend.enable_gc", sizeof("zend.enable_gc"), "0", sizeof("0")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
     362           2 : }
     363             : /* }}} */
     364             : 
     365             : /* {{{ proto int func_num_args(void)
     366             :    Get the number of arguments that were passed to the function */
     367          16 : ZEND_FUNCTION(func_num_args)
     368             : {
     369          16 :         zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
     370             : 
     371          16 :         if (ex && ex->function_state.arguments) {
     372          14 :                 RETURN_LONG((long)(zend_uintptr_t)*(ex->function_state.arguments));
     373             :         } else {
     374           2 :                 zend_error(E_WARNING, "func_num_args():  Called from the global scope - no function context");
     375           2 :                 RETURN_LONG(-1);
     376             :         }
     377             : }
     378             : /* }}} */
     379             : 
     380             : 
     381             : /* {{{ proto mixed func_get_arg(int arg_num)
     382             :    Get the $arg_num'th argument that was passed to the function */
     383          42 : ZEND_FUNCTION(func_get_arg)
     384             : {
     385             :         void **p;
     386             :         int arg_count;
     387             :         zval *arg;
     388             :         long requested_offset;
     389          42 :         zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
     390             : 
     391          42 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &requested_offset) == FAILURE) {
     392           5 :                 return;
     393             :         }
     394             : 
     395          37 :         if (requested_offset < 0) {
     396           4 :                 zend_error(E_WARNING, "func_get_arg():  The argument number should be >= 0");
     397           4 :                 RETURN_FALSE;
     398             :         }
     399             : 
     400          33 :         if (!ex || !ex->function_state.arguments) {
     401           3 :                 zend_error(E_WARNING, "func_get_arg():  Called from the global scope - no function context");
     402           3 :                 RETURN_FALSE;
     403             :         }
     404             : 
     405          30 :         p = ex->function_state.arguments;
     406          30 :         arg_count = (int)(zend_uintptr_t) *p;           /* this is the amount of arguments passed to func_get_arg(); */
     407             : 
     408          30 :         if (requested_offset >= arg_count) {
     409          16 :                 zend_error(E_WARNING, "func_get_arg():  Argument %ld not passed to function", requested_offset);
     410          16 :                 RETURN_FALSE;
     411             :         }
     412             : 
     413          14 :         arg = *(p-(arg_count-requested_offset));
     414          14 :         *return_value = *arg;
     415          14 :         zval_copy_ctor(return_value);
     416          14 :         INIT_PZVAL(return_value);
     417             : }
     418             : /* }}} */
     419             : 
     420             : 
     421             : /* {{{ proto array func_get_args()
     422             :    Get an array of the arguments that were passed to the function */
     423          79 : ZEND_FUNCTION(func_get_args)
     424             : {
     425             :         void **p;
     426             :         int arg_count;
     427             :         int i;
     428          79 :         zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
     429             : 
     430          79 :         if (!ex || !ex->function_state.arguments) {
     431           2 :                 zend_error(E_WARNING, "func_get_args():  Called from the global scope - no function context");
     432           2 :                 RETURN_FALSE;
     433             :         }
     434             : 
     435          77 :         p = ex->function_state.arguments;
     436          77 :         arg_count = (int)(zend_uintptr_t) *p;           /* this is the amount of arguments passed to func_get_args(); */
     437             : 
     438          77 :         array_init_size(return_value, arg_count);
     439         168 :         for (i=0; i<arg_count; i++) {
     440             :                 zval *element;
     441             : 
     442          91 :                 ALLOC_ZVAL(element);
     443          91 :                 *element = **((zval **) (p-(arg_count-i)));
     444          91 :                 zval_copy_ctor(element);
     445          91 :                 INIT_PZVAL(element);
     446          91 :                 zend_hash_next_index_insert(return_value->value.ht, &element, sizeof(zval *), NULL);
     447             :         }
     448             : }
     449             : /* }}} */
     450             : 
     451             : 
     452             : /* {{{ proto int strlen(string str)
     453             :    Get string length */
     454      789475 : ZEND_FUNCTION(strlen)
     455             : {
     456             :         char *s1;
     457             :         int s1_len;
     458             : 
     459      789475 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s1, &s1_len) == FAILURE) {
     460          38 :                 return;
     461             :         }
     462             : 
     463      789437 :         RETVAL_LONG(s1_len);
     464             : }
     465             : /* }}} */
     466             : 
     467             : 
     468             : /* {{{ proto int strcmp(string str1, string str2)
     469             :    Binary safe string comparison */
     470      365785 : ZEND_FUNCTION(strcmp)
     471             : {
     472             :         char *s1, *s2;
     473             :         int s1_len, s2_len;
     474             :         
     475      365785 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1_len, &s2, &s2_len) == FAILURE) {
     476           5 :                 return;
     477             :         }
     478             : 
     479      365780 :         RETURN_LONG(zend_binary_strcmp(s1, s1_len, s2, s2_len));
     480             : }
     481             : /* }}} */
     482             : 
     483             : 
     484             : /* {{{ proto int strncmp(string str1, string str2, int len)
     485             :    Binary safe string comparison */
     486       13141 : ZEND_FUNCTION(strncmp)
     487             : {
     488             :         char *s1, *s2;
     489             :         int s1_len, s2_len;
     490             :         long len;
     491             : 
     492       13141 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &s1, &s1_len, &s2, &s2_len, &len) == FAILURE) {
     493          20 :                 return;
     494             :         }
     495             : 
     496       13121 :         if (len < 0) {
     497           3 :                 zend_error(E_WARNING, "Length must be greater than or equal to 0");
     498           3 :                 RETURN_FALSE;
     499             :         }
     500             : 
     501       13118 :         RETURN_LONG(zend_binary_strncmp(s1, s1_len, s2, s2_len, len));
     502             : }
     503             : /* }}} */
     504             : 
     505             : 
     506             : /* {{{ proto int strcasecmp(string str1, string str2)
     507             :    Binary safe case-insensitive string comparison */
     508         816 : ZEND_FUNCTION(strcasecmp)
     509             : {
     510             :         char *s1, *s2;
     511             :         int s1_len, s2_len;
     512             :         
     513         816 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1_len, &s2, &s2_len) == FAILURE) {
     514           6 :                 return;
     515             :         }
     516             : 
     517         810 :         RETURN_LONG(zend_binary_strcasecmp(s1, s1_len, s2, s2_len));
     518             : }
     519             : /* }}} */
     520             : 
     521             : 
     522             : /* {{{ proto int strncasecmp(string str1, string str2, int len)
     523             :    Binary safe string comparison */
     524       19548 : ZEND_FUNCTION(strncasecmp)
     525             : {
     526             :         char *s1, *s2;
     527             :         int s1_len, s2_len;
     528             :         long len;
     529             : 
     530       19548 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &s1, &s1_len, &s2, &s2_len, &len) == FAILURE) {
     531          32 :                 return;
     532             :         }
     533             : 
     534       19516 :         if (len < 0) {
     535           3 :                 zend_error(E_WARNING, "Length must be greater than or equal to 0");
     536           3 :                 RETURN_FALSE;
     537             :         }
     538             : 
     539       19513 :         RETURN_LONG(zend_binary_strncasecmp(s1, s1_len, s2, s2_len, len));
     540             : }
     541             : /* }}} */
     542             : 
     543             : 
     544             : /* {{{ proto array each(array arr)
     545             :    Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element */
     546        1453 : ZEND_FUNCTION(each)
     547             : {
     548             :         zval *array, *entry, **entry_ptr, *tmp;
     549             :         char *string_key;
     550             :         uint string_key_len;
     551             :         ulong num_key;
     552             :         zval **inserted_pointer;
     553             :         HashTable *target_hash;
     554             : 
     555        1453 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &array) == FAILURE) {
     556           5 :                 return;
     557             :         }
     558             : 
     559        1448 :         target_hash = HASH_OF(array);
     560        1448 :         if (!target_hash) {
     561          29 :                 zend_error(E_WARNING,"Variable passed to each() is not an array or object");
     562          29 :                 return;
     563             :         }
     564        1419 :         if (zend_hash_get_current_data(target_hash, (void **) &entry_ptr)==FAILURE) {
     565          59 :                 RETURN_FALSE;
     566             :         }
     567        1360 :         array_init(return_value);
     568        1360 :         entry = *entry_ptr;
     569             : 
     570             :         /* add value elements */
     571        2720 :         if (Z_ISREF_P(entry)) {
     572           3 :                 ALLOC_ZVAL(tmp);
     573           3 :                 *tmp = *entry;
     574           3 :                 zval_copy_ctor(tmp);
     575             :                 Z_UNSET_ISREF_P(tmp);
     576             :                 Z_SET_REFCOUNT_P(tmp, 0);
     577           3 :                 entry=tmp;
     578             :         }
     579        1360 :         zend_hash_index_update(return_value->value.ht, 1, &entry, sizeof(zval *), NULL);
     580        1360 :         Z_ADDREF_P(entry);
     581        1360 :         zend_hash_update(return_value->value.ht, "value", sizeof("value"), &entry, sizeof(zval *), NULL);
     582        1360 :         Z_ADDREF_P(entry);
     583             : 
     584             :         /* add the key elements */
     585        1360 :         switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 1, NULL)) {
     586             :                 case HASH_KEY_IS_STRING:
     587          43 :                         add_get_index_stringl(return_value, 0, string_key, string_key_len-1, (void **) &inserted_pointer, 0);
     588          43 :                         break;
     589             :                 case HASH_KEY_IS_LONG:
     590        1317 :                         add_get_index_long(return_value, 0, num_key, (void **) &inserted_pointer);
     591             :                         break;
     592             :         }
     593        1360 :         zend_hash_update(return_value->value.ht, "key", sizeof("key"), inserted_pointer, sizeof(zval *), NULL);
     594        1360 :         Z_ADDREF_PP(inserted_pointer);
     595        1360 :         zend_hash_move_forward(target_hash);
     596             : }
     597             : /* }}} */
     598             : 
     599             : 
     600             : /* {{{ proto int error_reporting([int new_error_level])
     601             :    Return the current error_reporting level, and if an argument was passed - change to the new level */
     602        1898 : ZEND_FUNCTION(error_reporting)
     603             : {
     604             :         char *err;
     605             :         int err_len;
     606             :         int old_error_reporting;
     607             : 
     608        1898 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &err, &err_len) == FAILURE) {
     609           0 :                 return;
     610             :         }
     611             : 
     612        1898 :         old_error_reporting = EG(error_reporting);
     613        1898 :         if(ZEND_NUM_ARGS() != 0) {
     614         244 :                 zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), err, err_len, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
     615             :         }
     616             : 
     617        1898 :         RETVAL_LONG(old_error_reporting);
     618             : }
     619             : /* }}} */
     620             : 
     621             : 
     622             : /* {{{ proto bool define(string constant_name, mixed value, boolean case_insensitive=false)
     623             :    Define a new constant */
     624        3077 : ZEND_FUNCTION(define)
     625             : {
     626             :         char *name;
     627             :         int name_len;
     628             :         zval *val;
     629        3077 :         zval *val_free = NULL;
     630        3077 :         zend_bool non_cs = 0;
     631        3077 :         int case_sensitive = CONST_CS;
     632             :         zend_constant c;
     633             : 
     634        3077 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &name, &name_len, &val, &non_cs) == FAILURE) {
     635           4 :                 return;
     636             :         }
     637             : 
     638        3073 :         if(non_cs) {
     639         126 :                 case_sensitive = 0;
     640             :         }
     641             : 
     642             :         /* class constant, check if there is name and make sure class is valid & exists */
     643        3073 :         if (zend_memnstr(name, "::", sizeof("::") - 1, name + name_len)) {
     644           3 :                 zend_error(E_WARNING, "Class constants cannot be defined or redefined");
     645           3 :                 RETURN_FALSE;
     646             :         }
     647             : 
     648             : repeat:
     649        3070 :         switch (Z_TYPE_P(val)) {
     650             :                 case IS_LONG:
     651             :                 case IS_DOUBLE:
     652             :                 case IS_STRING:
     653             :                 case IS_BOOL:
     654             :                 case IS_RESOURCE:
     655             :                 case IS_NULL:
     656        3065 :                         break;
     657             :                 case IS_OBJECT:
     658           4 :                         if (!val_free) {
     659           4 :                                 if (Z_OBJ_HT_P(val)->get) {
     660           0 :                                         val_free = val = Z_OBJ_HT_P(val)->get(val TSRMLS_CC);
     661           0 :                                         goto repeat;
     662           4 :                                 } else if (Z_OBJ_HT_P(val)->cast_object) {
     663           4 :                                         ALLOC_INIT_ZVAL(val_free);
     664           4 :                                         if (Z_OBJ_HT_P(val)->cast_object(val, val_free, IS_STRING TSRMLS_CC) == SUCCESS) {
     665           1 :                                                 val = val_free;
     666           1 :                                                 break;
     667             :                                         }
     668             :                                 }
     669             :                         }
     670             :                         /* no break */
     671             :                 default:
     672           4 :                         zend_error(E_WARNING,"Constants may only evaluate to scalar values");
     673           4 :                         if (val_free) {
     674           3 :                                 zval_ptr_dtor(&val_free);
     675             :                         }
     676           4 :                         RETURN_FALSE;
     677             :         }
     678             :         
     679        3066 :         c.value = *val;
     680        3066 :         zval_copy_ctor(&c.value);
     681        3066 :         if (val_free) {
     682           1 :                 zval_ptr_dtor(&val_free);
     683             :         }
     684        3066 :         c.flags = case_sensitive; /* non persistent */
     685        3066 :         c.name = zend_strndup(name, name_len);
     686        3066 :         c.name_len = name_len+1;
     687        3066 :         c.module_number = PHP_USER_CONSTANT;
     688        3066 :         if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {
     689        3060 :                 RETURN_TRUE;
     690             :         } else {
     691           6 :                 RETURN_FALSE;
     692             :         }
     693             : }
     694             : /* }}} */
     695             : 
     696             : 
     697             : /* {{{ proto bool defined(string constant_name)
     698             :    Check whether a constant exists */
     699         164 : ZEND_FUNCTION(defined)
     700             : {
     701             :         char *name;
     702             :         int name_len;
     703             :         zval c;
     704             : 
     705         164 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
     706           0 :                 return;
     707             :         }
     708             :         
     709         164 :         if (zend_get_constant_ex(name, name_len, &c, NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC)) {
     710         139 :                 zval_dtor(&c);
     711         139 :                 RETURN_TRUE;
     712             :         } else {
     713          25 :                 RETURN_FALSE;
     714             :         }
     715             : }
     716             : /* }}} */
     717             : 
     718             : 
     719             : /* {{{ proto string get_class([object object])
     720             :    Retrieves the class name */
     721         854 : ZEND_FUNCTION(get_class)
     722             : {
     723         854 :         zval *obj = NULL;
     724         854 :         char *name = "";
     725         854 :         zend_uint name_len = 0;
     726             :         int dup;
     727             : 
     728         854 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o!", &obj) == FAILURE) {
     729          24 :                 RETURN_FALSE;
     730             :         }
     731             : 
     732         830 :         if (!obj) {
     733          11 :                 if (EG(scope)) {
     734           6 :                         RETURN_STRINGL(EG(scope)->name, EG(scope)->name_length, 1);
     735             :                 } else {
     736           5 :                         zend_error(E_WARNING, "get_class() called without object from outside a class");
     737           5 :                         RETURN_FALSE;
     738             :                 }
     739             :         }
     740             : 
     741         819 :         dup = zend_get_object_classname(obj, &name, &name_len TSRMLS_CC);
     742             : 
     743         819 :         RETURN_STRINGL(name, name_len, dup);
     744             : }
     745             : /* }}} */
     746             : 
     747             : 
     748             : /* {{{ proto string get_called_class()
     749             :    Retrieves the "Late Static Binding" class name */
     750          33 : ZEND_FUNCTION(get_called_class)
     751             : {
     752          33 :         if (zend_parse_parameters_none() == FAILURE) {
     753           0 :                 return;
     754             :         }
     755             : 
     756          33 :         if (EG(called_scope)) {
     757          31 :                 RETURN_STRINGL(EG(called_scope)->name, EG(called_scope)->name_length, 1);
     758           2 :         } else if (!EG(scope))  {
     759           2 :                 zend_error(E_WARNING, "get_called_class() called from outside a class");
     760             :         }
     761           2 :         RETURN_FALSE;
     762             : }
     763             : /* }}} */
     764             : 
     765             : 
     766             : /* {{{ proto string get_parent_class([mixed object])
     767             :    Retrieves the parent class name for object or class or current scope. */
     768          61 : ZEND_FUNCTION(get_parent_class)
     769             : {
     770             :         zval *arg;
     771          61 :         zend_class_entry *ce = NULL;
     772             :         char *name;
     773             :         zend_uint name_length;
     774             :         
     775          61 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &arg) == FAILURE) {
     776           1 :                 return;
     777             :         }
     778             : 
     779          60 :         if (!ZEND_NUM_ARGS()) {
     780           5 :                 ce = EG(scope);
     781           5 :                 if (ce && ce->parent) {
     782           2 :                         RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
     783             :                 } else {
     784           3 :                         RETURN_FALSE;
     785             :                 }
     786             :         }
     787             : 
     788          55 :         if (Z_TYPE_P(arg) == IS_OBJECT) {
     789          57 :                 if (Z_OBJ_HT_P(arg)->get_class_name
     790          38 :                         && Z_OBJ_HT_P(arg)->get_class_name(arg, &name, &name_length, 1 TSRMLS_CC) == SUCCESS) {
     791           3 :                         RETURN_STRINGL(name, name_length, 0);
     792             :                 } else {
     793          16 :                         ce = zend_get_class_entry(arg TSRMLS_CC);
     794             :                 }
     795          36 :         } else if (Z_TYPE_P(arg) == IS_STRING) {
     796             :                 zend_class_entry **pce;
     797             :                 
     798          12 :                 if (zend_lookup_class(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &pce TSRMLS_CC) == SUCCESS) {
     799           5 :                         ce = *pce;
     800             :                 }
     801             :         }
     802             : 
     803          52 :         if (ce && ce->parent) {
     804           2 :                 RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
     805             :         } else {
     806          50 :                 RETURN_FALSE;
     807             :         }
     808             : }
     809             : /* }}} */
     810             : 
     811             : 
     812         559 : static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
     813             : {
     814             :         zval *obj;
     815             :         char *class_name;
     816             :         int class_name_len;
     817             :         zend_class_entry *instance_ce;
     818             :         zend_class_entry **ce;
     819         559 :         zend_bool allow_string = only_subclass;
     820             :         zend_bool retval;
     821             : 
     822         559 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|b", &obj, &class_name, &class_name_len, &allow_string) == FAILURE) {
     823          17 :                 return;
     824             :         }
     825             :         /*
     826             :            allow_string - is_a default is no, is_subclass_of is yes. 
     827             :            if it's allowed, then the autoloader will be called if the class does not exist.
     828             :            default behaviour is different, as 'is_a' usage is normally to test mixed return values 
     829             :         */
     830             : 
     831         626 :         if (allow_string && Z_TYPE_P(obj) == IS_STRING) {
     832             :                 zend_class_entry **the_ce;
     833         172 :                 if (zend_lookup_class(Z_STRVAL_P(obj), Z_STRLEN_P(obj), &the_ce TSRMLS_CC) == FAILURE) {
     834          88 :                         RETURN_FALSE;
     835             :                 }
     836          84 :                 instance_ce = *the_ce;
     837         510 :         } else if (Z_TYPE_P(obj) == IS_OBJECT && HAS_CLASS_ENTRY(*obj)) {
     838         140 :                 instance_ce = Z_OBJCE_P(obj);
     839             :         } else {
     840         230 :                 RETURN_FALSE;
     841             :         }
     842             : 
     843         224 :         if (zend_lookup_class_ex(class_name, class_name_len, 0, &ce TSRMLS_CC) == FAILURE) {
     844          83 :                 retval = 0;
     845             :         } else {
     846         164 :                 if (only_subclass && instance_ce == *ce) {
     847          23 :                         retval = 0;
     848             :                 } else {
     849         118 :                         retval = instanceof_function(instance_ce, *ce TSRMLS_CC);
     850             :                 }
     851             :         }
     852             : 
     853         224 :         RETURN_BOOL(retval);
     854             : }
     855             : 
     856             : 
     857             : /* {{{ proto bool is_subclass_of(mixed object_or_string, string class_name [, bool allow_string=true])
     858             :    Returns true if the object has this class as one of its parents */
     859         299 : ZEND_FUNCTION(is_subclass_of)
     860             : {
     861         299 :         is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
     862         299 : }
     863             : /* }}} */
     864             : 
     865             : 
     866             : /* {{{ proto bool is_a(mixed object_or_string, string class_name [, bool allow_string=false])
     867             :    Returns true if the first argument is an object and is this class or has this class as one of its parents, */
     868         260 : ZEND_FUNCTION(is_a)
     869             : {
     870         260 :         is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     871         260 : }
     872             : /* }}} */
     873             : 
     874             : 
     875             : /* {{{ add_class_vars */
     876          76 : static void add_class_vars(zend_class_entry *ce, HashTable *properties, zval *return_value TSRMLS_DC)
     877             : {
     878          76 :         if (zend_hash_num_elements(properties) > 0) {
     879             :                 HashPosition pos;
     880             :                 zval **prop;
     881             : 
     882          51 :                 zend_hash_internal_pointer_reset_ex(properties, &pos);
     883         300 :                 while (zend_hash_get_current_data_ex(properties, (void **) &prop, &pos) == SUCCESS) {
     884             :                         char *key, *class_name, *prop_name;
     885             :                         uint key_len;
     886             :                         ulong num_index;
     887         198 :                         int prop_name_len = 0;                  
     888             :                         zval *prop_copy;
     889             :                         zend_property_info *property_info;
     890             :                         zval zprop_name;
     891             : 
     892         198 :                         zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos);
     893         198 :                         zend_hash_move_forward_ex(properties, &pos);
     894             : 
     895         198 :                         zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
     896         198 :                         prop_name_len = strlen(prop_name);
     897             : 
     898         198 :                         ZVAL_STRINGL(&zprop_name, prop_name, prop_name_len, 0);
     899         198 :                         property_info = zend_get_property_info(ce, &zprop_name, 1 TSRMLS_CC);
     900             : 
     901         198 :                         if (!property_info || property_info == &EG(std_property_info)) {
     902          46 :                                 continue;
     903             :                         }
     904             : 
     905             :                         /* copy: enforce read only access */
     906         152 :                         ALLOC_ZVAL(prop_copy);
     907         152 :                         *prop_copy = **prop;
     908         152 :                         zval_copy_ctor(prop_copy);
     909         152 :                         INIT_PZVAL(prop_copy);
     910             : 
     911             :                         /* this is necessary to make it able to work with default array 
     912             :                         * properties, returned to user */
     913         152 :                         if (Z_TYPE_P(prop_copy) == IS_CONSTANT_ARRAY || (Z_TYPE_P(prop_copy) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
     914           0 :                                 zval_update_constant(&prop_copy, 0 TSRMLS_CC);
     915             :                         }
     916             : 
     917         152 :                         add_assoc_zval(return_value, prop_name, prop_copy);
     918             :                 }
     919             :         }
     920          76 : }
     921             : /* }}} */
     922             : 
     923             : 
     924             : /* {{{ proto array get_class_vars(string class_name)
     925             :    Returns an array of default properties of the class. */
     926          65 : ZEND_FUNCTION(get_class_vars)
     927             : {
     928             :         char *class_name;
     929             :         int class_name_len;
     930             :         zend_class_entry **pce;
     931             : 
     932          65 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &class_name, &class_name_len) == FAILURE) {
     933           7 :                 return;
     934             :         }
     935             : 
     936          58 :         if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC) == FAILURE) {
     937          20 :                 RETURN_FALSE;
     938             :         } else {
     939          38 :                 array_init(return_value);
     940          38 :                 zend_update_class_constants(*pce TSRMLS_CC);
     941          38 :                 add_class_vars(*pce, &(*pce)->default_properties, return_value TSRMLS_CC);
     942          38 :                 add_class_vars(*pce, CE_STATIC_MEMBERS(*pce), return_value TSRMLS_CC);
     943             :         }
     944             : }
     945             : /* }}} */
     946             : 
     947             : 
     948             : /* {{{ proto array get_object_vars(object obj)
     949             :    Returns an array of object properties */
     950          68 : ZEND_FUNCTION(get_object_vars)
     951             : {
     952             :         zval *obj;
     953             :         zval **value;
     954             :         HashTable *properties;
     955             :         HashPosition pos;
     956             :         char *key, *prop_name, *class_name;
     957             :         uint key_len;
     958             :         ulong num_index;
     959             :         zend_object *zobj;
     960             : 
     961          68 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
     962          28 :                 return;
     963             :         }
     964             : 
     965          40 :         if (Z_OBJ_HT_P(obj)->get_properties == NULL) {
     966           0 :                 RETURN_FALSE;
     967             :         }
     968             : 
     969          40 :         properties = Z_OBJ_HT_P(obj)->get_properties(obj TSRMLS_CC);
     970             : 
     971          40 :         if (properties == NULL) {
     972           0 :                 RETURN_FALSE;
     973             :         }
     974             : 
     975          40 :         zobj = zend_objects_get_address(obj TSRMLS_CC);
     976             : 
     977          40 :         array_init(return_value);
     978             : 
     979          40 :         zend_hash_internal_pointer_reset_ex(properties, &pos);
     980             : 
     981         279 :         while (zend_hash_get_current_data_ex(properties, (void **) &value, &pos) == SUCCESS) {
     982         199 :                 if (zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos) == HASH_KEY_IS_STRING) {
     983         196 :                         if (zend_check_property_access(zobj, key, key_len-1 TSRMLS_CC) == SUCCESS) {
     984         168 :                                 zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
     985             :                                 /* Not separating references */
     986         168 :                                 Z_ADDREF_PP(value);
     987         168 :                                 add_assoc_zval_ex(return_value, prop_name, strlen(prop_name)+1, *value);
     988             :                         }
     989             :                 }
     990         199 :                 zend_hash_move_forward_ex(properties, &pos);
     991             :         }
     992             : }
     993             : /* }}} */
     994             : 
     995             : 
     996             : /* {{{ proto array get_class_methods(mixed class)
     997             :    Returns an array of method names for class or class instance. */
     998          70 : ZEND_FUNCTION(get_class_methods)
     999             : {
    1000             :         zval *klass;
    1001             :         zval *method_name;
    1002          70 :         zend_class_entry *ce = NULL, **pce;
    1003             :         HashPosition pos;
    1004             :         zend_function *mptr;
    1005             : 
    1006          70 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &klass) == FAILURE) {
    1007           2 :                 return;
    1008             :         }
    1009             : 
    1010          68 :         if (Z_TYPE_P(klass) == IS_OBJECT) {
    1011             :                 /* TBI!! new object handlers */
    1012           9 :                 if (!HAS_CLASS_ENTRY(*klass)) {
    1013           0 :                         RETURN_FALSE;
    1014             :                 }
    1015           9 :                 ce = Z_OBJCE_P(klass);
    1016          59 :         } else if (Z_TYPE_P(klass) == IS_STRING) {
    1017          37 :                 if (zend_lookup_class(Z_STRVAL_P(klass), Z_STRLEN_P(klass), &pce TSRMLS_CC) == SUCCESS) {
    1018          32 :                         ce = *pce;
    1019             :                 }
    1020             :         }
    1021             : 
    1022          68 :         if (!ce) {
    1023          27 :                 RETURN_NULL();
    1024             :         }
    1025             : 
    1026          41 :         array_init(return_value);
    1027          41 :         zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
    1028             : 
    1029         318 :         while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
    1030         420 :                 if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC) 
    1031          63 :                  || (EG(scope) &&
    1032          46 :                      (((mptr->common.fn_flags & ZEND_ACC_PROTECTED) &&
    1033          22 :                        zend_check_protected(mptr->common.scope, EG(scope)))
    1034          29 :                    || ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
    1035          24 :                        EG(scope) == mptr->common.scope)))) {
    1036             :                         char *key;
    1037             :                         uint key_len;
    1038             :                         ulong num_index;
    1039         198 :                         uint len = strlen(mptr->common.function_name);
    1040             : 
    1041             :                         /* Do not display old-style inherited constructors */
    1042         228 :                         if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 ||
    1043          16 :                             mptr->common.scope == ce ||
    1044           7 :                             zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 0, &pos) != HASH_KEY_IS_STRING ||
    1045           7 :                             zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0) {
    1046             : 
    1047         198 :                                 MAKE_STD_ZVAL(method_name);
    1048         198 :                                 ZVAL_STRINGL(method_name, mptr->common.function_name, len, 1);
    1049         198 :                                 zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
    1050             :                         }
    1051             :                 }
    1052         236 :                 zend_hash_move_forward_ex(&ce->function_table, &pos);
    1053             :         }
    1054             : }
    1055             : /* }}} */
    1056             : 
    1057             : 
    1058             : /* {{{ proto bool method_exists(object object, string method)
    1059             :    Checks if the class method exists */
    1060         135 : ZEND_FUNCTION(method_exists)
    1061             : {
    1062             :         zval *klass; 
    1063             :         char *method_name;
    1064             :         int method_len;
    1065             :         char *lcname;
    1066             :         zend_class_entry * ce, **pce;
    1067             : 
    1068         135 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &klass, &method_name, &method_len) == FAILURE) {
    1069           8 :                 return;
    1070             :         }
    1071         127 :         if (Z_TYPE_P(klass) == IS_OBJECT) {
    1072          73 :                 ce = Z_OBJCE_P(klass);
    1073          54 :         } else if (Z_TYPE_P(klass) == IS_STRING) {
    1074          32 :                 if (zend_lookup_class(Z_STRVAL_P(klass), Z_STRLEN_P(klass), &pce TSRMLS_CC) == FAILURE) {
    1075           5 :                         RETURN_FALSE;
    1076             :                 }
    1077          27 :                 ce = *pce;
    1078             :         } else {
    1079          22 :                 RETURN_FALSE;
    1080             :         }
    1081             : 
    1082         100 :         lcname = zend_str_tolower_dup(method_name, method_len);
    1083         100 :         if (zend_hash_exists(&ce->function_table, lcname, method_len+1)) {
    1084          67 :                 efree(lcname);
    1085          67 :                 RETURN_TRUE;
    1086             :         } else {
    1087          33 :                 union _zend_function *func = NULL;
    1088             : 
    1089         126 :                 if (Z_TYPE_P(klass) == IS_OBJECT 
    1090          63 :                 && Z_OBJ_HT_P(klass)->get_method != NULL
    1091          60 :                 && (func = Z_OBJ_HT_P(klass)->get_method(&klass, method_name, method_len TSRMLS_CC)) != NULL
    1092             :                 ) {
    1093           6 :                         if (func->type == ZEND_INTERNAL_FUNCTION 
    1094           6 :                         && (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0
    1095             :                         ) {
    1096             :                                 /* Returns true to the fake Closure's __invoke */
    1097           3 :                                 RETVAL_BOOL((func->common.scope == zend_ce_closure
    1098             :                                         && (method_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
    1099             :                                         && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0) ? 1 : 0);
    1100             : 
    1101           3 :                                 efree(lcname);
    1102           3 :                                 efree(((zend_internal_function*)func)->function_name);
    1103           3 :                                 efree(func);
    1104           3 :                                 return;
    1105             :                         }
    1106           0 :                         efree(lcname);
    1107           0 :                         RETURN_TRUE;
    1108             :                 }
    1109             :         }
    1110          30 :         efree(lcname);
    1111          30 :         RETURN_FALSE;
    1112             : }
    1113             : /* }}} */
    1114             : 
    1115             : /* {{{ proto bool property_exists(mixed object_or_class, string property_name)
    1116             :    Checks if the object or class has a property */
    1117         121 : ZEND_FUNCTION(property_exists)
    1118             : {
    1119             :         zval *object;
    1120             :         char *property;
    1121             :         int property_len;
    1122             :         zend_class_entry *ce, **pce;
    1123             :         zend_property_info *property_info;
    1124             :         zval property_z;
    1125             :         ulong h;
    1126             : 
    1127         121 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &object, &property, &property_len) == FAILURE) {
    1128           4 :                 return;
    1129             :         }
    1130             : 
    1131         117 :         if (property_len == 0) {
    1132           7 :                 RETURN_FALSE;
    1133             :         }
    1134             : 
    1135         110 :         if (Z_TYPE_P(object) == IS_STRING) {
    1136          60 :                 if (zend_lookup_class(Z_STRVAL_P(object), Z_STRLEN_P(object), &pce TSRMLS_CC) == FAILURE) {
    1137           2 :                         RETURN_FALSE;
    1138             :                 }
    1139          58 :                 ce = *pce;
    1140          50 :         } else if (Z_TYPE_P(object) == IS_OBJECT) {
    1141          44 :                 ce = Z_OBJCE_P(object);
    1142             :         } else {
    1143           6 :                 zend_error(E_WARNING, "First parameter must either be an object or the name of an existing class");
    1144           6 :                 RETURN_NULL();
    1145             :         }
    1146             : 
    1147         102 :         h = zend_get_hash_value(property, property_len+1);
    1148         379 :         if (zend_hash_quick_find(&ce->properties_info, property, property_len+1, h, (void **) &property_info) == SUCCESS
    1149         379 :                 && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
    1150          66 :                 RETURN_TRUE;
    1151             :         }
    1152             : 
    1153          36 :         ZVAL_STRINGL(&property_z, property, property_len, 0);
    1154             : 
    1155          76 :         if (Z_TYPE_P(object) ==  IS_OBJECT &&
    1156          20 :                 Z_OBJ_HANDLER_P(object, has_property) && 
    1157          20 :                 Z_OBJ_HANDLER_P(object, has_property)(object, &property_z, 2 TSRMLS_CC)) {
    1158           9 :                 RETURN_TRUE;
    1159             :         }
    1160          27 :         RETURN_FALSE;
    1161             : }
    1162             : /* }}} */
    1163             : 
    1164             : 
    1165             : /* {{{ proto bool class_exists(string classname [, bool autoload])
    1166             :    Checks if the class exists */
    1167         320 : ZEND_FUNCTION(class_exists)
    1168             : {
    1169             :         char *class_name, *lc_name;
    1170             :         zend_class_entry **ce;
    1171             :         int class_name_len;
    1172             :         int found;
    1173         320 :         zend_bool autoload = 1;
    1174             :         ALLOCA_FLAG(use_heap)
    1175             : 
    1176         320 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &class_name, &class_name_len, &autoload) == FAILURE) {
    1177          17 :                 return;
    1178             :         }
    1179             : 
    1180         303 :         if (!autoload) {
    1181             :                 char *name;
    1182             :                 int len;
    1183             : 
    1184          62 :                 lc_name = do_alloca(class_name_len + 1, use_heap);
    1185          62 :                 zend_str_tolower_copy(lc_name, class_name, class_name_len);
    1186             : 
    1187             :                 /* Ignore leading "\" */
    1188          62 :                 name = lc_name;
    1189          62 :                 len = class_name_len;
    1190          62 :                 if (lc_name[0] == '\\') {
    1191           0 :                         name = &lc_name[1];
    1192           0 :                         len--;
    1193             :                 }
    1194             :         
    1195          62 :                 found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce);
    1196          62 :                 free_alloca(lc_name, use_heap);
    1197          62 :                 RETURN_BOOL(found == SUCCESS && !((*ce)->ce_flags & ZEND_ACC_INTERFACE));
    1198             :         }
    1199             : 
    1200         241 :         if (zend_lookup_class(class_name, class_name_len, &ce TSRMLS_CC) == SUCCESS) {
    1201         167 :                 RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_INTERFACE) == 0);
    1202             :         } else {
    1203          74 :                 RETURN_FALSE;
    1204             :         }
    1205             : }
    1206             : /* }}} */
    1207             : 
    1208             : /* {{{ proto bool interface_exists(string classname [, bool autoload])
    1209             :    Checks if the class exists */
    1210         103 : ZEND_FUNCTION(interface_exists)
    1211             : {
    1212             :         char *iface_name, *lc_name;
    1213             :         zend_class_entry **ce;
    1214             :         int iface_name_len;
    1215             :         int found;
    1216         103 :         zend_bool autoload = 1;
    1217             :         ALLOCA_FLAG(use_heap)
    1218             : 
    1219         103 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &iface_name, &iface_name_len, &autoload) == FAILURE) {
    1220          16 :                 return;
    1221             :         }
    1222             : 
    1223          87 :         if (!autoload) {
    1224             :                 char *name;
    1225             :                 int len;
    1226             :                 
    1227          17 :                 lc_name = do_alloca(iface_name_len + 1, use_heap);
    1228          17 :                 zend_str_tolower_copy(lc_name, iface_name, iface_name_len);
    1229             :         
    1230             :                 /* Ignore leading "\" */
    1231          17 :                 name = lc_name;
    1232          17 :                 len = iface_name_len;
    1233          17 :                 if (lc_name[0] == '\\') {
    1234           0 :                         name = &lc_name[1];
    1235           0 :                         len--;
    1236             :                 }
    1237             : 
    1238          17 :                 found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce);
    1239          17 :                 free_alloca(lc_name, use_heap);
    1240          17 :                 RETURN_BOOL(found == SUCCESS && (*ce)->ce_flags & ZEND_ACC_INTERFACE);
    1241             :         }
    1242             : 
    1243          70 :         if (zend_lookup_class(iface_name, iface_name_len, &ce TSRMLS_CC) == SUCCESS) {
    1244          31 :                 RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_INTERFACE) > 0);
    1245             :         } else {
    1246          39 :                 RETURN_FALSE;
    1247             :         }
    1248             : }
    1249             : /* }}} */
    1250             : 
    1251             : 
    1252             : /* {{{ proto bool function_exists(string function_name) 
    1253             :    Checks if the function exists */
    1254        4765 : ZEND_FUNCTION(function_exists)
    1255             : {
    1256             :         char *name;
    1257             :         int name_len;
    1258             :         zend_function *func;
    1259             :         char *lcname;
    1260             :         zend_bool retval;
    1261             :         
    1262        4765 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
    1263           6 :                 return;
    1264             :         }
    1265             : 
    1266        4759 :         lcname = zend_str_tolower_dup(name, name_len);
    1267             :         
    1268             :         /* Ignore leading "\" */
    1269        4759 :         name = lcname;
    1270        4759 :         if (lcname[0] == '\\') {
    1271           1 :                 name = &lcname[1];
    1272           1 :                 name_len--;
    1273             :         }
    1274             : 
    1275        4759 :         retval = (zend_hash_find(EG(function_table), name, name_len+1, (void **)&func) == SUCCESS);
    1276             :         
    1277        4759 :         efree(lcname);
    1278             : 
    1279             :         /*
    1280             :          * A bit of a hack, but not a bad one: we see if the handler of the function
    1281             :          * is actually one that displays "function is disabled" message.
    1282             :          */
    1283        7875 :         if (retval && func->type == ZEND_INTERNAL_FUNCTION &&
    1284        3116 :                 func->internal_function.handler == zif_display_disabled_function) {
    1285           0 :                 retval = 0;
    1286             :         }
    1287             : 
    1288        4759 :         RETURN_BOOL(retval);
    1289             : }
    1290             : /* }}} */
    1291             : 
    1292             : /* {{{ proto bool class_alias(string user_class_name , string alias_name [, bool autoload])
    1293             :    Creates an alias for user defined class */
    1294          28 : ZEND_FUNCTION(class_alias)
    1295             : {
    1296             :         char *class_name, *lc_name, *alias_name;
    1297             :         zend_class_entry **ce;
    1298             :         int class_name_len, alias_name_len;
    1299             :         int found;
    1300          28 :         zend_bool autoload = 1;
    1301             :         ALLOCA_FLAG(use_heap)
    1302             : 
    1303          28 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &class_name, &class_name_len, &alias_name, &alias_name_len, &autoload) == FAILURE) {
    1304           0 :                 return;
    1305             :         }
    1306             : 
    1307          28 :         if (!autoload) {
    1308           0 :                 lc_name = do_alloca(class_name_len + 1, use_heap);
    1309           0 :                 zend_str_tolower_copy(lc_name, class_name, class_name_len);
    1310             :         
    1311           0 :                 found = zend_hash_find(EG(class_table), lc_name, class_name_len+1, (void **) &ce);
    1312           0 :                 free_alloca(lc_name, use_heap);
    1313             :         } else {
    1314          28 :                 found = zend_lookup_class(class_name, class_name_len, &ce TSRMLS_CC);
    1315             :         }
    1316          28 :         if (found == SUCCESS) {
    1317          27 :                 if ((*ce)->type == ZEND_USER_CLASS) { 
    1318          26 :                         if (zend_register_class_alias_ex(alias_name, alias_name_len, *ce TSRMLS_CC) == SUCCESS) {
    1319          22 :                                 RETURN_TRUE;
    1320             :                         } else {
    1321           4 :                                 zend_error(E_WARNING, "Cannot redeclare class %s", alias_name);
    1322           4 :                                 RETURN_FALSE;
    1323             :                         }
    1324             :                 } else {
    1325           1 :                         zend_error(E_WARNING, "First argument of class_alias() must be a name of user defined class");
    1326           1 :                         RETURN_FALSE;
    1327             :                 }
    1328             :         } else {
    1329           1 :                 zend_error(E_WARNING, "Class '%s' not found", class_name);
    1330           1 :                 RETURN_FALSE;
    1331             :         }
    1332             : }
    1333             : /* }}} */
    1334             : 
    1335             : #if ZEND_DEBUG
    1336             : /* {{{ proto void leak(int num_bytes=3)
    1337             :    Cause an intentional memory leak, for testing/debugging purposes */
    1338             : ZEND_FUNCTION(leak)
    1339             : {
    1340             :         long leakbytes=3;
    1341             : 
    1342             :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &leakbytes) == FAILURE) {
    1343             :                 return;
    1344             :         }
    1345             : 
    1346             :         emalloc(leakbytes);
    1347             : }
    1348             : /* }}} */
    1349             : 
    1350             : 
    1351             : #ifdef ZEND_TEST_EXCEPTIONS
    1352             : ZEND_FUNCTION(crash)
    1353             : {
    1354             :         char *nowhere=NULL;
    1355             : 
    1356             :         memcpy(nowhere, "something", sizeof("something"));
    1357             : }
    1358             : #endif
    1359             : 
    1360             : #endif /* ZEND_DEBUG */
    1361             : 
    1362             : /* {{{ proto array get_included_files(void)
    1363             :    Returns an array with the file names that were include_once()'d */
    1364          11 : ZEND_FUNCTION(get_included_files)
    1365             : {
    1366             :         char *entry;
    1367          11 :         if (zend_parse_parameters_none() == FAILURE) {
    1368           3 :                 return;
    1369             :         }
    1370             : 
    1371           8 :         array_init(return_value);
    1372           8 :         zend_hash_internal_pointer_reset(&EG(included_files));
    1373          31 :         while (zend_hash_get_current_key(&EG(included_files), &entry, NULL, 1) == HASH_KEY_IS_STRING) {
    1374          15 :                 add_next_index_string(return_value, entry, 0);
    1375          15 :                 zend_hash_move_forward(&EG(included_files));
    1376             :         }
    1377             : }
    1378             : /* }}} */
    1379             : 
    1380             : 
    1381             : /* {{{ proto void trigger_error(string message [, int error_type])
    1382             :    Generates a user-level error/warning/notice message */
    1383          20 : ZEND_FUNCTION(trigger_error)
    1384             : {
    1385          20 :         long error_type = E_USER_NOTICE;
    1386             :         char *message;
    1387             :         int message_len;
    1388             : 
    1389          20 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &message, &message_len, &error_type) == FAILURE) {
    1390           2 :                 return;
    1391             :         }
    1392             : 
    1393          18 :         switch (error_type) {
    1394             :                 case E_USER_ERROR:
    1395             :                 case E_USER_WARNING:
    1396             :                 case E_USER_NOTICE:
    1397             :                 case E_USER_DEPRECATED:
    1398          16 :                         break;
    1399             :                 default:
    1400           2 :                         zend_error(E_WARNING, "Invalid error type specified");
    1401           2 :                         RETURN_FALSE;
    1402             :                         break;
    1403             :         }
    1404             : 
    1405          16 :         zend_error((int)error_type, "%s", message);
    1406          15 :         RETURN_TRUE;
    1407             : }
    1408             : /* }}} */
    1409             : 
    1410             : 
    1411             : /* {{{ proto string set_error_handler(string error_handler [, int error_types])
    1412             :    Sets a user-defined error handler function.  Returns the previously defined error handler, or false on error */
    1413         238 : ZEND_FUNCTION(set_error_handler)
    1414             : {
    1415             :         zval *error_handler;
    1416         238 :         zend_bool had_orig_error_handler=0;
    1417         238 :         char *error_handler_name = NULL;
    1418         238 :         long error_type = E_ALL | E_STRICT;
    1419             : 
    1420         238 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &error_handler, &error_type) == FAILURE) {
    1421           0 :                 return;
    1422             :         }
    1423             : 
    1424         238 :         if (!zend_is_callable(error_handler, 0, &error_handler_name TSRMLS_CC)) {
    1425           0 :                 zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
    1426           0 :                                    get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown");
    1427           0 :                 efree(error_handler_name);
    1428           0 :                 return;
    1429             :         }
    1430         238 :         efree(error_handler_name);
    1431             : 
    1432         238 :         if (EG(user_error_handler)) {
    1433           3 :                 had_orig_error_handler = 1;
    1434           3 :                 *return_value = *EG(user_error_handler);
    1435           3 :                 zval_copy_ctor(return_value);
    1436           3 :                 INIT_PZVAL(return_value);
    1437           3 :                 zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting)));
    1438           3 :                 zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler));
    1439             :         }
    1440         238 :         ALLOC_ZVAL(EG(user_error_handler));
    1441             : 
    1442         238 :         if (!zend_is_true(error_handler)) { /* unset user-defined handler */
    1443           0 :                 FREE_ZVAL(EG(user_error_handler));
    1444           0 :                 EG(user_error_handler) = NULL;
    1445           0 :                 RETURN_TRUE;
    1446             :         }
    1447             : 
    1448         238 :         EG(user_error_handler_error_reporting) = (int)error_type;
    1449         238 :         *EG(user_error_handler) = *error_handler;
    1450         238 :         zval_copy_ctor(EG(user_error_handler));
    1451         238 :         INIT_PZVAL(EG(user_error_handler));
    1452             : 
    1453         238 :         if (!had_orig_error_handler) {
    1454         235 :                 RETURN_NULL();
    1455             :         }
    1456             : }
    1457             : /* }}} */
    1458             : 
    1459             : 
    1460             : /* {{{ proto void restore_error_handler(void)
    1461             :    Restores the previously defined error handler function */
    1462           2 : ZEND_FUNCTION(restore_error_handler)
    1463             : {
    1464           2 :         if (EG(user_error_handler)) {
    1465           2 :                 zval *zeh = EG(user_error_handler);
    1466             : 
    1467           2 :                 EG(user_error_handler) = NULL;
    1468           2 :                 zval_ptr_dtor(&zeh);
    1469             :         }
    1470             : 
    1471           2 :         if (zend_ptr_stack_num_elements(&EG(user_error_handlers))==0) {
    1472           2 :                 EG(user_error_handler) = NULL;
    1473             :         } else {
    1474           0 :                 EG(user_error_handler_error_reporting) = zend_stack_int_top(&EG(user_error_handlers_error_reporting));
    1475           0 :                 zend_stack_del_top(&EG(user_error_handlers_error_reporting));
    1476           0 :                 EG(user_error_handler) = zend_ptr_stack_pop(&EG(user_error_handlers));
    1477             :         }
    1478           2 :         RETURN_TRUE;
    1479             : }
    1480             : /* }}} */
    1481             : 
    1482             : 
    1483             : /* {{{ proto string set_exception_handler(callable exception_handler)
    1484             :    Sets a user-defined exception handler function.  Returns the previously defined exception handler, or false on error */
    1485          17 : ZEND_FUNCTION(set_exception_handler)
    1486             : {
    1487             :         zval *exception_handler;
    1488          17 :         char *exception_handler_name = NULL;
    1489          17 :         zend_bool had_orig_exception_handler=0;
    1490             : 
    1491          17 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &exception_handler) == FAILURE) {
    1492           2 :                 return;
    1493             :         }
    1494             : 
    1495          15 :         if (Z_TYPE_P(exception_handler) != IS_NULL) { /* NULL == unset */
    1496          15 :                 if (!zend_is_callable(exception_handler, 0, &exception_handler_name TSRMLS_CC)) {
    1497           2 :                         zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
    1498           2 :                                            get_active_function_name(TSRMLS_C), exception_handler_name?exception_handler_name:"unknown");
    1499           2 :                         efree(exception_handler_name);
    1500           2 :                         return;
    1501             :                 }
    1502          13 :                 efree(exception_handler_name);
    1503             :         }
    1504             : 
    1505          13 :         if (EG(user_exception_handler)) {
    1506           2 :                 had_orig_exception_handler = 1;
    1507           2 :                 *return_value = *EG(user_exception_handler);
    1508           2 :                 zval_copy_ctor(return_value);
    1509           2 :                 zend_ptr_stack_push(&EG(user_exception_handlers), EG(user_exception_handler));
    1510             :         }
    1511          13 :         ALLOC_ZVAL(EG(user_exception_handler));
    1512             : 
    1513          13 :         if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */
    1514           0 :                 FREE_ZVAL(EG(user_exception_handler));
    1515           0 :                 EG(user_exception_handler) = NULL;
    1516           0 :                 RETURN_TRUE;
    1517             :         }
    1518             : 
    1519          13 :         MAKE_COPY_ZVAL(&exception_handler, EG(user_exception_handler))
    1520             : 
    1521          13 :         if (!had_orig_exception_handler) {
    1522          11 :                 RETURN_NULL();
    1523             :         }
    1524             : }
    1525             : /* }}} */
    1526             : 
    1527             : 
    1528             : /* {{{ proto void restore_exception_handler(void)
    1529             :    Restores the previously defined exception handler function */
    1530           1 : ZEND_FUNCTION(restore_exception_handler)
    1531             : {
    1532           1 :         if (EG(user_exception_handler)) {
    1533           1 :                 zval_ptr_dtor(&EG(user_exception_handler));
    1534             :         }
    1535           1 :         if (zend_ptr_stack_num_elements(&EG(user_exception_handlers))==0) {
    1536           0 :                 EG(user_exception_handler) = NULL;
    1537             :         } else {
    1538           1 :                 EG(user_exception_handler) = zend_ptr_stack_pop(&EG(user_exception_handlers));
    1539             :         }
    1540           1 :         RETURN_TRUE;
    1541             : }
    1542             : /* }}} */
    1543             : 
    1544           2 : static int same_name(const char *key, const char *name, zend_uint name_len)
    1545             : {
    1546           2 :         char *lcname = zend_str_tolower_dup(name, name_len);
    1547           2 :         int ret = memcmp(lcname, key, name_len) == 0;
    1548           2 :         efree(lcname);
    1549           2 :         return ret;
    1550             : }
    1551             : 
    1552        2552 : static int copy_class_or_interface_name(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
    1553             : {
    1554        2552 :         zval *array = va_arg(args, zval *);
    1555        2552 :         zend_uint mask = va_arg(args, zend_uint);
    1556        2552 :         zend_uint comply = va_arg(args, zend_uint);
    1557        2552 :         zend_uint comply_mask = (comply)? mask:0;
    1558        2552 :         zend_class_entry *ce  = *pce;
    1559             : 
    1560        5102 :         if ((hash_key->nKeyLength==0 || hash_key->arKey[0]!=0)
    1561        2550 :                 && (comply_mask == (ce->ce_flags & mask))) {
    1562        1282 :                 if (ce->refcount > 1 && 
    1563           2 :                     (ce->name_length != hash_key->nKeyLength - 1 || 
    1564           2 :                      !same_name(hash_key->arKey, ce->name, ce->name_length))) {
    1565           1 :                         add_next_index_stringl(array, hash_key->arKey, hash_key->nKeyLength - 1, 1);
    1566             :                 } else {
    1567        1276 :                         add_next_index_stringl(array, ce->name, ce->name_length, 1);
    1568             :                 }
    1569             :         }
    1570        2552 :         return ZEND_HASH_APPLY_KEEP;
    1571             : }
    1572             : 
    1573             : 
    1574             : /* {{{ proto array get_declared_classes()
    1575             :    Returns an array of all declared classes. */
    1576           9 : ZEND_FUNCTION(get_declared_classes)
    1577             : {
    1578           9 :         zend_uint mask = ZEND_ACC_INTERFACE;
    1579           9 :         zend_uint comply = 0;
    1580             : 
    1581           9 :         if (zend_parse_parameters_none() == FAILURE) {
    1582           1 :                 return;
    1583             :         }
    1584             : 
    1585           8 :         array_init(return_value);
    1586           8 :         zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
    1587             : }
    1588             : /* }}} */
    1589             : 
    1590             : /* {{{ proto array get_declared_interfaces()
    1591             :    Returns an array of all declared interfaces. */
    1592          10 : ZEND_FUNCTION(get_declared_interfaces)
    1593             : {
    1594          10 :         zend_uint mask = ZEND_ACC_INTERFACE;
    1595          10 :         zend_uint comply = 1;
    1596             : 
    1597          10 :         if (zend_parse_parameters_none() == FAILURE) {
    1598           2 :                 return;
    1599             :         }
    1600             : 
    1601           8 :         array_init(return_value);
    1602           8 :         zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
    1603             : }
    1604             : /* }}} */
    1605             : 
    1606             : 
    1607        9205 : static int copy_function_name(zend_function *func TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
    1608             : {
    1609        9205 :         zval *internal_ar = va_arg(args, zval *),
    1610        9205 :              *user_ar     = va_arg(args, zval *);
    1611             : 
    1612        9205 :         if (hash_key->nKeyLength == 0 || hash_key->arKey[0] == 0) {
    1613           0 :                 return 0;
    1614             :         }
    1615             : 
    1616        9205 :         if (func->type == ZEND_INTERNAL_FUNCTION) {
    1617        9196 :                 add_next_index_stringl(internal_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
    1618           9 :         } else if (func->type == ZEND_USER_FUNCTION) {
    1619           9 :                 add_next_index_stringl(user_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
    1620             :         }
    1621             : 
    1622        9205 :         return 0;
    1623             : }
    1624             : 
    1625             : 
    1626             : /* {{{ proto array get_defined_functions(void)
    1627             :    Returns an array of all defined functions */
    1628           6 : ZEND_FUNCTION(get_defined_functions)
    1629             : {
    1630             :         zval *internal;
    1631             :         zval *user;
    1632             : 
    1633           6 :         if (zend_parse_parameters_none() == FAILURE) {
    1634           2 :                 return;
    1635             :         }
    1636             : 
    1637           4 :         MAKE_STD_ZVAL(internal);
    1638           4 :         MAKE_STD_ZVAL(user);
    1639             : 
    1640           4 :         array_init(internal);
    1641           4 :         array_init(user);
    1642           4 :         array_init(return_value);
    1643             : 
    1644           4 :         zend_hash_apply_with_arguments(EG(function_table) TSRMLS_CC, (apply_func_args_t) copy_function_name, 2, internal, user);
    1645             : 
    1646           4 :         if (zend_hash_add(Z_ARRVAL_P(return_value), "internal", sizeof("internal"), (void **)&internal, sizeof(zval *), NULL) == FAILURE) {
    1647           0 :                 zval_ptr_dtor(&internal);
    1648           0 :                 zval_ptr_dtor(&user);
    1649           0 :                 zval_dtor(return_value);
    1650           0 :                 zend_error(E_WARNING, "Cannot add internal functions to return value from get_defined_functions()");
    1651           0 :                 RETURN_FALSE;
    1652             :         }
    1653             : 
    1654           4 :         if (zend_hash_add(Z_ARRVAL_P(return_value), "user", sizeof("user"), (void **)&user, sizeof(zval *), NULL) == FAILURE) {
    1655           0 :                 zval_ptr_dtor(&user);
    1656           0 :                 zval_dtor(return_value);
    1657           0 :                 zend_error(E_WARNING, "Cannot add user functions to return value from get_defined_functions()");
    1658           0 :                 RETURN_FALSE;
    1659             :         }
    1660             : }
    1661             : /* }}} */
    1662             : 
    1663             : 
    1664             : /* {{{ proto array get_defined_vars(void)
    1665             :    Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */
    1666          17 : ZEND_FUNCTION(get_defined_vars)
    1667             : {
    1668          17 :         if (!EG(active_symbol_table)) {
    1669           6 :                 zend_rebuild_symbol_table(TSRMLS_C);
    1670             :         }
    1671             : 
    1672          17 :         array_init_size(return_value, zend_hash_num_elements(EG(active_symbol_table)));
    1673             : 
    1674          17 :         zend_hash_copy(Z_ARRVAL_P(return_value), EG(active_symbol_table),
    1675             :                                         (copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval *));
    1676          17 : }
    1677             : /* }}} */
    1678             : 
    1679             : 
    1680             : #define LAMBDA_TEMP_FUNCNAME    "__lambda_func"
    1681             : /* {{{ proto string create_function(string args, string code)
    1682             :    Creates an anonymous function, and returns its name (funny, eh?) */
    1683          57 : ZEND_FUNCTION(create_function)
    1684             : {
    1685             :         char *eval_code, *function_name, *function_args, *function_code;
    1686             :         int eval_code_length, function_name_length, function_args_len, function_code_len;
    1687             :         int retval;
    1688             :         char *eval_name;
    1689             : 
    1690          57 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &function_args, &function_args_len, &function_code, &function_code_len) == FAILURE) {
    1691           0 :                 return;
    1692             :         }
    1693             : 
    1694          57 :         eval_code = (char *) emalloc(sizeof("function " LAMBDA_TEMP_FUNCNAME)
    1695             :                         +function_args_len
    1696             :                         +2      /* for the args parentheses */
    1697             :                         +2      /* for the curly braces */
    1698             :                         +function_code_len);
    1699             : 
    1700          57 :         eval_code_length = sizeof("function " LAMBDA_TEMP_FUNCNAME "(") - 1;
    1701          57 :         memcpy(eval_code, "function " LAMBDA_TEMP_FUNCNAME "(", eval_code_length);
    1702             : 
    1703          57 :         memcpy(eval_code + eval_code_length, function_args, function_args_len);
    1704          57 :         eval_code_length += function_args_len;
    1705             : 
    1706          57 :         eval_code[eval_code_length++] = ')';
    1707          57 :         eval_code[eval_code_length++] = '{';
    1708             : 
    1709          57 :         memcpy(eval_code + eval_code_length, function_code, function_code_len);
    1710          57 :         eval_code_length += function_code_len;
    1711             : 
    1712          57 :         eval_code[eval_code_length++] = '}';
    1713          57 :         eval_code[eval_code_length] = '\0';
    1714             : 
    1715          57 :         eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC);
    1716          57 :         retval = zend_eval_stringl(eval_code, eval_code_length, NULL, eval_name TSRMLS_CC);
    1717          57 :         efree(eval_code);
    1718          57 :         efree(eval_name);
    1719             : 
    1720          57 :         if (retval==SUCCESS) {
    1721             :                 zend_function new_function, *func;
    1722             : 
    1723          55 :                 if (zend_hash_find(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **) &func)==FAILURE) {
    1724           0 :                         zend_error(E_ERROR, "Unexpected inconsistency in create_function()");
    1725           0 :                         RETURN_FALSE;
    1726             :                 }
    1727          55 :                 new_function = *func;
    1728          55 :                 function_add_ref(&new_function);
    1729             : 
    1730          55 :                 function_name = (char *) emalloc(sizeof("0lambda_")+MAX_LENGTH_OF_LONG);
    1731          55 :                 function_name[0] = '\0';
    1732             : 
    1733             :                 do {
    1734          55 :                         function_name_length = 1 + snprintf(function_name + 1, sizeof("lambda_")+MAX_LENGTH_OF_LONG, "lambda_%d", ++EG(lambda_count));
    1735          55 :                 } while (zend_hash_add(EG(function_table), function_name, function_name_length+1, &new_function, sizeof(zend_function), NULL)==FAILURE);
    1736          55 :                 zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
    1737          55 :                 RETURN_STRINGL(function_name, function_name_length, 0);
    1738             :         } else {
    1739           2 :                 zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
    1740           2 :                 RETURN_FALSE;
    1741             :         }
    1742             : }
    1743             : /* }}} */
    1744             : 
    1745             : 
    1746             : #if ZEND_DEBUG
    1747             : ZEND_FUNCTION(zend_test_func)
    1748             : {
    1749             :         zval *arg1, *arg2;
    1750             : 
    1751             :         zend_get_parameters(ht, 2, &arg1, &arg2);
    1752             : }
    1753             : 
    1754             : 
    1755             : #ifdef ZTS
    1756             : ZEND_FUNCTION(zend_thread_id)
    1757             : {
    1758             :         RETURN_LONG((long)tsrm_thread_id());
    1759             : }
    1760             : #endif
    1761             : #endif
    1762             : 
    1763             : /* {{{ proto string get_resource_type(resource res)
    1764             :    Get the resource type name for a given resource */
    1765          77 : ZEND_FUNCTION(get_resource_type)
    1766             : {
    1767             :         char *resource_type;
    1768             :         zval *z_resource_type;
    1769             : 
    1770          77 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_resource_type) == FAILURE) {
    1771          12 :                 return;
    1772             :         }
    1773             : 
    1774          65 :         resource_type = zend_rsrc_list_get_rsrc_type(Z_LVAL_P(z_resource_type) TSRMLS_CC);
    1775          65 :         if (resource_type) {
    1776          40 :                 RETURN_STRING(resource_type, 1);
    1777             :         } else {
    1778          25 :                 RETURN_STRING("Unknown", 1);
    1779             :         }
    1780             : }
    1781             : /* }}} */
    1782             : 
    1783             : 
    1784         300 : static int add_extension_info(zend_module_entry *module, void *arg TSRMLS_DC)
    1785             : {
    1786         300 :         zval *name_array = (zval *)arg;
    1787         300 :         add_next_index_string(name_array, module->name, 1);
    1788         300 :         return 0;
    1789             : }
    1790             : 
    1791           0 : static int add_zendext_info(zend_extension *ext, void *arg TSRMLS_DC)
    1792             : {
    1793           0 :         zval *name_array = (zval *)arg;
    1794           0 :         add_next_index_string(name_array, ext->name, 1);
    1795           0 :         return 0;
    1796             : }
    1797             : 
    1798       18243 : static int add_constant_info(zend_constant *constant, void *arg TSRMLS_DC)
    1799             : {
    1800       18243 :         zval *name_array = (zval *)arg;
    1801             :         zval *const_val;
    1802             : 
    1803       18243 :         MAKE_STD_ZVAL(const_val);
    1804       18243 :         *const_val = constant->value;
    1805       18243 :         zval_copy_ctor(const_val);
    1806       18243 :         INIT_PZVAL(const_val);
    1807       18243 :         add_assoc_zval_ex(name_array, constant->name, constant->name_len, const_val);
    1808       18243 :         return 0;
    1809             : }
    1810             : 
    1811             : 
    1812             : /* {{{ proto array get_loaded_extensions([bool zend_extensions]) U
    1813             :    Return an array containing names of loaded extensions */
    1814           7 : ZEND_FUNCTION(get_loaded_extensions)
    1815             : {
    1816           7 :         zend_bool zendext = 0;
    1817             : 
    1818           7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &zendext) == FAILURE) {
    1819           1 :                 return;
    1820             :         }
    1821             : 
    1822           6 :         array_init(return_value);
    1823             : 
    1824           6 :         if (zendext) {
    1825           2 :                 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) add_zendext_info, return_value TSRMLS_CC);
    1826             :         } else {
    1827           4 :                 zend_hash_apply_with_argument(&module_registry, (apply_func_arg_t) add_extension_info, return_value TSRMLS_CC);
    1828             :         }
    1829             : }
    1830             : /* }}} */
    1831             : 
    1832             : 
    1833             : /* {{{ proto array get_defined_constants([bool categorize])
    1834             :    Return an array containing the names and values of all defined constants */
    1835          15 : ZEND_FUNCTION(get_defined_constants)
    1836             : {
    1837          15 :         zend_bool categorize = 0;
    1838             :         
    1839          15 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &categorize) == FAILURE) {
    1840           2 :                 return;
    1841             :         }
    1842             : 
    1843          13 :         array_init(return_value);
    1844             : 
    1845          13 :         if (categorize) {
    1846             :                 HashPosition pos;
    1847             :                 zend_constant *val;
    1848             :                 int module_number;
    1849             :                 zval **modules;
    1850             :                 char **module_names;
    1851             :                 zend_module_entry *module;
    1852           5 :                 int i = 1;
    1853             : 
    1854           5 :                 modules = ecalloc(zend_hash_num_elements(&module_registry) + 2, sizeof(zval *));
    1855           5 :                 module_names = emalloc((zend_hash_num_elements(&module_registry) + 2) * sizeof(char *));
    1856             : 
    1857           5 :                 module_names[0] = "internal";
    1858           5 :                 zend_hash_internal_pointer_reset_ex(&module_registry, &pos);
    1859         385 :                 while (zend_hash_get_current_data_ex(&module_registry, (void *) &module, &pos) != FAILURE) {
    1860         375 :                         module_names[module->module_number] = (char *)module->name;
    1861         375 :                         i++;
    1862         375 :                         zend_hash_move_forward_ex(&module_registry, &pos);
    1863             :                 }
    1864           5 :                 module_names[i] = "user";
    1865             : 
    1866           5 :                 zend_hash_internal_pointer_reset_ex(EG(zend_constants), &pos);
    1867       11411 :                 while (zend_hash_get_current_data_ex(EG(zend_constants), (void **) &val, &pos) != FAILURE) {
    1868             :                         zval *const_val;
    1869             : 
    1870       11401 :                         if (val->module_number == PHP_USER_CONSTANT) {
    1871           1 :                                 module_number = i;
    1872       11400 :                         } else if (val->module_number > i || val->module_number < 0) {
    1873             :                                 /* should not happen */
    1874             :                                 goto bad_module_id;
    1875             :                         } else {
    1876       11400 :                                 module_number = val->module_number;
    1877             :                         }
    1878             : 
    1879       11401 :                         if (!modules[module_number]) {
    1880         221 :                                 MAKE_STD_ZVAL(modules[module_number]);
    1881         221 :                                 array_init(modules[module_number]);
    1882         221 :                                 add_assoc_zval(return_value, module_names[module_number], modules[module_number]);
    1883             :                         }
    1884             : 
    1885       11401 :                         MAKE_STD_ZVAL(const_val);
    1886       11401 :                         *const_val = val->value;
    1887       11401 :                         zval_copy_ctor(const_val);
    1888       11401 :                         INIT_PZVAL(const_val);
    1889             : 
    1890       11401 :                         add_assoc_zval_ex(modules[module_number], val->name, val->name_len, const_val);
    1891             : bad_module_id:
    1892       11401 :                         zend_hash_move_forward_ex(EG(zend_constants), &pos);
    1893             :                 }
    1894           5 :                 efree(module_names);
    1895           5 :                 efree(modules);
    1896             :         } else {
    1897           8 :                 zend_hash_apply_with_argument(EG(zend_constants), (apply_func_arg_t) add_constant_info, return_value TSRMLS_CC);
    1898             :         }
    1899             : }
    1900             : /* }}} */
    1901             : 
    1902             : 
    1903        2711 : static zval *debug_backtrace_get_args(void **curpos TSRMLS_DC)
    1904             : {
    1905        2711 :         void **p = curpos;
    1906             :         zval *arg_array, **arg;
    1907        2711 :         int arg_count = (int)(zend_uintptr_t) *p;
    1908             : 
    1909        2711 :         MAKE_STD_ZVAL(arg_array);
    1910        2711 :         array_init_size(arg_array, arg_count);
    1911        2711 :         p -= arg_count;
    1912             : 
    1913       10561 :         while (--arg_count >= 0) {
    1914        5139 :                 arg = (zval **) p++;
    1915        5139 :                 if (*arg) {
    1916        5139 :                         if (Z_TYPE_PP(arg) != IS_OBJECT) {
    1917       25994 :                                 SEPARATE_ZVAL_TO_MAKE_IS_REF(arg);
    1918             :                         }
    1919        5139 :                         Z_ADDREF_PP(arg);
    1920        5139 :                         add_next_index_zval(arg_array, *arg);
    1921             :                 } else {
    1922           0 :                         add_next_index_null(arg_array);
    1923             :                 }
    1924             :         }
    1925             : 
    1926        2711 :         return arg_array;
    1927             : }
    1928             : 
    1929          29 : void debug_print_backtrace_args(zval *arg_array TSRMLS_DC)
    1930             : {
    1931             :         zval **tmp;
    1932             :         HashPosition iterator;
    1933          29 :         int i = 0;
    1934             : 
    1935          29 :         zend_hash_internal_pointer_reset_ex(arg_array->value.ht, &iterator);
    1936         106 :         while (zend_hash_get_current_data_ex(arg_array->value.ht, (void **) &tmp, &iterator) == SUCCESS) {
    1937          48 :                 if (i++) {
    1938          28 :                         ZEND_PUTS(", ");
    1939             :                 }
    1940          48 :                 zend_print_flat_zval_r(*tmp TSRMLS_CC);
    1941          48 :                 zend_hash_move_forward_ex(arg_array->value.ht, &iterator);
    1942             :         }
    1943          29 : }
    1944             : 
    1945             : /* {{{ proto void debug_print_backtrace([int options]) */
    1946          15 : ZEND_FUNCTION(debug_print_backtrace)
    1947             : {
    1948             :         zend_execute_data *ptr, *skip;
    1949             :         int lineno;
    1950             :         char *function_name;
    1951             :         char *filename;
    1952          15 :         char *class_name = NULL;
    1953             :         char *call_type;
    1954          15 :         char *include_filename = NULL;
    1955          15 :         zval *arg_array = NULL;
    1956          15 :         int indent = 0;
    1957          15 :         long options = 0;
    1958             : 
    1959          15 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &options) == FAILURE) {
    1960           0 :                 return;
    1961             :         }
    1962             : 
    1963          15 :         ptr = EG(current_execute_data);
    1964             : 
    1965             :         /* skip debug_backtrace() */
    1966          15 :         ptr = ptr->prev_execute_data;
    1967             : 
    1968          68 :         while (ptr) {
    1969          38 :                 char *free_class_name = NULL;
    1970             : 
    1971          38 :                 class_name = call_type = NULL;   
    1972          38 :                 arg_array = NULL;
    1973             : 
    1974          38 :                 skip = ptr;
    1975             :                 /* skip internal handler */
    1976          53 :                 if (!skip->op_array &&
    1977           3 :                     skip->prev_execute_data &&
    1978           3 :                     skip->prev_execute_data->opline &&
    1979           3 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
    1980           3 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
    1981           3 :                     skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    1982           1 :                         skip = skip->prev_execute_data;
    1983             :                 }
    1984             : 
    1985          38 :                 if (skip->op_array) {
    1986          36 :                         filename = skip->op_array->filename;
    1987          36 :                         lineno = skip->opline->lineno;
    1988             :                 } else {
    1989           2 :                         filename = NULL;
    1990           2 :                         lineno = 0;
    1991             :                 }
    1992             : 
    1993          38 :                 function_name = ptr->function_state.function->common.function_name;
    1994             : 
    1995          38 :                 if (function_name) {
    1996          35 :                         if (ptr->object) {
    1997          10 :                                 if (ptr->function_state.function->common.scope) {
    1998          10 :                                         class_name = ptr->function_state.function->common.scope->name;
    1999             :                                 } else {
    2000             :                                         zend_uint class_name_len;
    2001             :                                         int dup;
    2002             : 
    2003           0 :                                         dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC);
    2004           0 :                                         if(!dup) {
    2005           0 :                                                 free_class_name = class_name;
    2006             :                                         }
    2007             :                                 }
    2008             : 
    2009          10 :                                 call_type = "->";
    2010          25 :                         } else if (ptr->function_state.function->common.scope) {
    2011          10 :                                 class_name = ptr->function_state.function->common.scope->name;
    2012          10 :                                 call_type = "::";
    2013             :                         } else {
    2014          15 :                                 class_name = NULL;
    2015          15 :                                 call_type = NULL;
    2016             :                         }
    2017          35 :                         if ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL))) {
    2018          35 :                                 if (ptr->function_state.arguments && (options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0) {
    2019          29 :                                         arg_array = debug_backtrace_get_args(ptr->function_state.arguments TSRMLS_CC);
    2020             :                                 }
    2021             :                         }
    2022             :                 } else {
    2023             :                         /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
    2024           3 :                         zend_bool build_filename_arg = 1;
    2025             : 
    2026           3 :                         if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    2027             :                                 /* can happen when calling eval from a custom sapi */
    2028           0 :                                 function_name = "unknown";
    2029           0 :                                 build_filename_arg = 0;
    2030             :                         } else
    2031           3 :                         switch (Z_LVAL(ptr->opline->op2.u.constant)) {
    2032             :                                 case ZEND_EVAL:
    2033           1 :                                         function_name = "eval";
    2034           1 :                                         build_filename_arg = 0;
    2035           1 :                                         break;
    2036             :                                 case ZEND_INCLUDE:
    2037           2 :                                         function_name = "include";
    2038           2 :                                         break;
    2039             :                                 case ZEND_REQUIRE:
    2040           0 :                                         function_name = "require";
    2041           0 :                                         break;
    2042             :                                 case ZEND_INCLUDE_ONCE:
    2043           0 :                                         function_name = "include_once";
    2044           0 :                                         break;
    2045             :                                 case ZEND_REQUIRE_ONCE:
    2046           0 :                                         function_name = "require_once";
    2047           0 :                                         break;
    2048             :                                 default:
    2049             :                                         /* this can actually happen if you use debug_backtrace() in your error_handler and 
    2050             :                                          * you're in the top-scope */
    2051           0 :                                         function_name = "unknown"; 
    2052           0 :                                         build_filename_arg = 0;
    2053             :                                         break;
    2054             :                         }
    2055             : 
    2056           3 :                         if (build_filename_arg && include_filename) {
    2057           0 :                                 MAKE_STD_ZVAL(arg_array);
    2058           0 :                                 array_init(arg_array);
    2059           0 :                                 add_next_index_string(arg_array, include_filename, 1);
    2060             :                         }
    2061           3 :                         call_type = NULL;
    2062             :                 }
    2063          38 :                 zend_printf("#%-2d ", indent);
    2064          38 :                 if (class_name) {
    2065          20 :                         ZEND_PUTS(class_name);
    2066          20 :                         ZEND_PUTS(call_type);
    2067             :                 }
    2068          38 :                 zend_printf("%s(", function_name);
    2069          38 :                 if (arg_array) {
    2070          29 :                         debug_print_backtrace_args(arg_array TSRMLS_CC);
    2071          29 :                         zval_ptr_dtor(&arg_array);
    2072             :                 }
    2073          38 :                 if (filename) {
    2074          36 :                         zend_printf(") called at [%s:%d]\n", filename, lineno);
    2075             :                 } else {
    2076           2 :                         zend_execute_data *prev = skip->prev_execute_data;
    2077             : 
    2078           4 :                         while (prev) {
    2079           4 :                                 if (prev->function_state.function &&
    2080           2 :                                         prev->function_state.function->common.type != ZEND_USER_FUNCTION) {
    2081           0 :                                         prev = NULL;
    2082           0 :                                         break;
    2083             :                                 }                                   
    2084           2 :                                 if (prev->op_array) {
    2085           2 :                                         zend_printf(") called at [%s:%d]\n", prev->op_array->filename, prev->opline->lineno);
    2086           2 :                                         break;
    2087             :                                 }
    2088           0 :                                 prev = prev->prev_execute_data;
    2089             :                         }
    2090           2 :                         if (!prev) {
    2091           0 :                                 ZEND_PUTS(")\n");
    2092             :                         }
    2093             :                 }
    2094          38 :                 include_filename = filename;
    2095          38 :                 ptr = skip->prev_execute_data;
    2096          38 :                 ++indent;
    2097          38 :                 if (free_class_name) {
    2098           0 :                         efree(free_class_name);
    2099             :                 }
    2100             :         }
    2101             : }
    2102             : 
    2103             : /* }}} */
    2104             : 
    2105        1590 : ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options TSRMLS_DC)
    2106             : {
    2107             :         zend_execute_data *ptr, *skip;
    2108             :         int lineno;
    2109             :         char *function_name;
    2110             :         char *filename;
    2111             :         char *class_name;
    2112        1590 :         char *include_filename = NULL;
    2113             :         zval *stack_frame;
    2114             : 
    2115        1590 :         ptr = EG(current_execute_data);
    2116             : 
    2117             :         /* skip "new Exception()" */
    2118        1590 :         if (ptr && (skip_last == 0) && ptr->opline && (ptr->opline->opcode == ZEND_NEW)) {
    2119         308 :                 ptr = ptr->prev_execute_data;
    2120             :         }
    2121             : 
    2122             :         /* skip debug_backtrace() */
    2123        1590 :         if (skip_last-- && ptr) {
    2124          37 :                 ptr = ptr->prev_execute_data;
    2125             :         }
    2126             : 
    2127        1590 :         array_init(return_value);
    2128             : 
    2129        6026 :         while (ptr) {
    2130        2846 :                 MAKE_STD_ZVAL(stack_frame);
    2131        2846 :                 array_init(stack_frame);
    2132             : 
    2133        2846 :                 skip = ptr;
    2134             :                 /* skip internal handler */
    2135        5835 :                 if (!skip->op_array &&
    2136         890 :                     skip->prev_execute_data &&
    2137         881 :                     skip->prev_execute_data->opline &&
    2138         605 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
    2139         532 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
    2140          81 :                     skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    2141          80 :                         skip = skip->prev_execute_data;
    2142             :                 }
    2143             : 
    2144        2846 :                 if (skip->op_array) {
    2145        2036 :                         filename = skip->op_array->filename;
    2146        2036 :                         lineno = skip->opline->lineno;
    2147        2036 :                         add_assoc_string_ex(stack_frame, "file", sizeof("file"), filename, 1);
    2148        2036 :                         add_assoc_long_ex(stack_frame, "line", sizeof("line"), lineno);
    2149             : 
    2150             :                         /* try to fetch args only if an FCALL was just made - elsewise we're in the middle of a function
    2151             :                          * and debug_baktrace() might have been called by the error_handler. in this case we don't 
    2152             :                          * want to pop anything of the argument-stack */
    2153             :                 } else {
    2154         810 :                         zend_execute_data *prev = skip->prev_execute_data;
    2155             : 
    2156        1622 :                         while (prev) {
    2157        3192 :                                 if (prev->function_state.function &&
    2158         803 :                                         prev->function_state.function->common.type != ZEND_USER_FUNCTION &&
    2159         793 :                                         !(prev->function_state.function->common.type == ZEND_INTERNAL_FUNCTION &&
    2160         793 :                                                 (prev->function_state.function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER))) {
    2161             :                                         break;
    2162             :                                 }                                   
    2163         271 :                                 if (prev->op_array) {
    2164         269 :                                         add_assoc_string_ex(stack_frame, "file", sizeof("file"), prev->op_array->filename, 1);
    2165         269 :                                         add_assoc_long_ex(stack_frame, "line", sizeof("line"), prev->opline->lineno);
    2166         269 :                                         break;
    2167             :                                 }
    2168           2 :                                 prev = prev->prev_execute_data;
    2169             :                         }
    2170         810 :                         filename = NULL;
    2171             :                 }
    2172             : 
    2173        2846 :                 function_name = ptr->function_state.function->common.function_name;
    2174             : 
    2175        2846 :                 if (function_name) {
    2176        2714 :                         add_assoc_string_ex(stack_frame, "function", sizeof("function"), function_name, 1);
    2177             : 
    2178        4769 :                         if (ptr->object && Z_TYPE_P(ptr->object) == IS_OBJECT) {
    2179        2055 :                                 if (ptr->function_state.function->common.scope) {
    2180        2055 :                                         add_assoc_string_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1);
    2181             :                                 } else {
    2182             :                                         zend_uint class_name_len;
    2183             :                                         int dup;
    2184             : 
    2185           0 :                                         dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC);
    2186           0 :                                         add_assoc_string_ex(stack_frame, "class", sizeof("class"), class_name, dup);
    2187             :                                         
    2188             :                                 }
    2189        2055 :                                 if ((options & DEBUG_BACKTRACE_PROVIDE_OBJECT) != 0) {
    2190          22 :                                         add_assoc_zval_ex(stack_frame, "object", sizeof("object"), ptr->object);
    2191          22 :                                         Z_ADDREF_P(ptr->object);
    2192             :                                 }
    2193             : 
    2194        2055 :                                 add_assoc_string_ex(stack_frame, "type", sizeof("type"), "->", 1);
    2195         659 :                         } else if (ptr->function_state.function->common.scope) {
    2196         178 :                                 add_assoc_string_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1);
    2197         178 :                                 add_assoc_string_ex(stack_frame, "type", sizeof("type"), "::", 1);
    2198             :                         }
    2199             : 
    2200        7479 :                         if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0 && 
    2201        4765 :                                 ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL)))) {
    2202        2693 :                                 if (ptr->function_state.arguments) {
    2203        2682 :                                         add_assoc_zval_ex(stack_frame, "args", sizeof("args"), debug_backtrace_get_args(ptr->function_state.arguments TSRMLS_CC));
    2204             :                                 }
    2205             :                         }
    2206             :                 } else {
    2207             :                         /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
    2208         132 :                         zend_bool build_filename_arg = 1;
    2209             : 
    2210         154 :                         if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    2211             :                                 /* can happen when calling eval from a custom sapi */
    2212          22 :                                 function_name = "unknown";
    2213          22 :                                 build_filename_arg = 0;
    2214             :                         } else
    2215         110 :                         switch (ptr->opline->op2.u.constant.value.lval) {
    2216             :                                 case ZEND_EVAL:
    2217          14 :                                         function_name = "eval";
    2218          14 :                                         build_filename_arg = 0;
    2219          14 :                                         break;
    2220             :                                 case ZEND_INCLUDE:
    2221          95 :                                         function_name = "include";
    2222          95 :                                         break;
    2223             :                                 case ZEND_REQUIRE:
    2224           1 :                                         function_name = "require";
    2225           1 :                                         break;
    2226             :                                 case ZEND_INCLUDE_ONCE:
    2227           0 :                                         function_name = "include_once";
    2228           0 :                                         break;
    2229             :                                 case ZEND_REQUIRE_ONCE:
    2230           0 :                                         function_name = "require_once";
    2231           0 :                                         break;
    2232             :                                 default:
    2233             :                                         /* this can actually happen if you use debug_backtrace() in your error_handler and 
    2234             :                                          * you're in the top-scope */
    2235           0 :                                         function_name = "unknown"; 
    2236           0 :                                         build_filename_arg = 0;
    2237             :                                         break;
    2238             :                         }
    2239             : 
    2240         132 :                         if (build_filename_arg && include_filename) {
    2241             :                                 zval *arg_array;
    2242             : 
    2243          94 :                                 MAKE_STD_ZVAL(arg_array);
    2244          94 :                                 array_init(arg_array);
    2245             : 
    2246             :                                 /* include_filename always points to the last filename of the last last called-fuction.
    2247             :                                    if we have called include in the frame above - this is the file we have included.
    2248             :                                  */
    2249             : 
    2250          94 :                                 add_next_index_string(arg_array, include_filename, 1);
    2251          94 :                                 add_assoc_zval_ex(stack_frame, "args", sizeof("args"), arg_array);
    2252             :                         }
    2253             : 
    2254         132 :                         add_assoc_string_ex(stack_frame, "function", sizeof("function"), function_name, 1);
    2255             :                 }
    2256             : 
    2257        2846 :                 add_next_index_zval(return_value, stack_frame);
    2258             : 
    2259        2846 :                 include_filename = filename; 
    2260             : 
    2261        2846 :                 ptr = skip->prev_execute_data;
    2262             :         }
    2263        1590 : }
    2264             : /* }}} */
    2265             : 
    2266             : 
    2267             : /* {{{ proto array debug_backtrace([int options])
    2268             :    Return backtrace as array */
    2269          35 : ZEND_FUNCTION(debug_backtrace)
    2270             : {
    2271          35 :         long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
    2272             :         
    2273          35 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &options) == FAILURE) {
    2274           0 :                 return;
    2275             :         }
    2276             : 
    2277          35 :         zend_fetch_debug_backtrace(return_value, 1, options TSRMLS_CC);
    2278             : }
    2279             : /* }}} */
    2280             : 
    2281             : /* {{{ proto bool extension_loaded(string extension_name)
    2282             :    Returns true if the named extension is loaded */
    2283        6152 : ZEND_FUNCTION(extension_loaded)
    2284             : {
    2285             :         char *extension_name;
    2286             :         int extension_name_len;
    2287             :         char *lcname;
    2288             : 
    2289        6152 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &extension_name, &extension_name_len) == FAILURE) {
    2290           0 :                 return;
    2291             :         }
    2292             : 
    2293        6152 :         lcname = zend_str_tolower_dup(extension_name, extension_name_len);
    2294        6152 :         if (zend_hash_exists(&module_registry, lcname, extension_name_len+1)) {
    2295        6149 :                 RETVAL_TRUE;
    2296             :         } else {
    2297           3 :                 RETVAL_FALSE;
    2298             :         }
    2299        6152 :         efree(lcname);
    2300             : }
    2301             : /* }}} */
    2302             : 
    2303             : 
    2304             : /* {{{ proto array get_extension_funcs(string extension_name)
    2305             :    Returns an array with the names of functions belonging to the named extension */
    2306          33 : ZEND_FUNCTION(get_extension_funcs)
    2307             : {
    2308             :         char *extension_name;
    2309             :         int extension_name_len;
    2310             :         zend_module_entry *module;
    2311             :         const zend_function_entry *func;
    2312             : 
    2313          33 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &extension_name, &extension_name_len) == FAILURE) {
    2314           7 :                 return;
    2315             :         }
    2316             : 
    2317          26 :         if (strncasecmp(extension_name, "zend", sizeof("zend"))) {
    2318          24 :                 char *lcname = zend_str_tolower_dup(extension_name, extension_name_len);
    2319          48 :                 if (zend_hash_find(&module_registry, lcname,
    2320          24 :                         extension_name_len+1, (void**)&module) == FAILURE) {
    2321          20 :                         efree(lcname);
    2322          20 :                         RETURN_FALSE;
    2323             :                 }
    2324           4 :                 efree(lcname);
    2325             : 
    2326           4 :                 if (!(func = module->functions)) {
    2327           0 :                         RETURN_FALSE;
    2328             :                 }
    2329             :         } else {
    2330           2 :                 func = builtin_functions;
    2331             :         }
    2332             : 
    2333           6 :         array_init(return_value);
    2334             : 
    2335        1780 :         while (func->fname) {
    2336        1768 :                 add_next_index_string(return_value, func->fname, 1);
    2337        1768 :                 func++;
    2338             :         }
    2339             : }
    2340             : /* }}} */
    2341             : 
    2342             : /*
    2343             :  * Local variables:
    2344             :  * tab-width: 4
    2345             :  * c-basic-offset: 4
    2346             :  * indent-tabs-mode: t
    2347             :  * End:
    2348             :  */

Generated by: LCOV version 1.10

Generated at Fri, 18 Apr 2014 07:01:23 +0000 (6 days ago)

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