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