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