xref: /PHP-7.0/Zend/zend_builtin_functions.c (revision f18cf46d)
1 /*
2    +----------------------------------------------------------------------+
3    | Zend Engine                                                          |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1998-2017 Zend Technologies Ltd. (http://www.zend.com) |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 2.00 of the Zend license,     |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.zend.com/license/2_00.txt.                                |
11    | If you did not receive a copy of the Zend license and are unable to  |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@zend.com so we can mail you a copy immediately.              |
14    +----------------------------------------------------------------------+
15    | Authors: Andi Gutmans <andi@zend.com>                                |
16    |          Zeev Suraski <zeev@zend.com>                                |
17    +----------------------------------------------------------------------+
18 */
19 
20 /* $Id$ */
21 
22 #include "zend.h"
23 #include "zend_API.h"
24 #include "zend_builtin_functions.h"
25 #include "zend_constants.h"
26 #include "zend_ini.h"
27 #include "zend_exceptions.h"
28 #include "zend_extensions.h"
29 #include "zend_closures.h"
30 #include "zend_generators.h"
31 
32 #undef ZEND_TEST_EXCEPTIONS
33 
34 #if ZEND_DEBUG
35 static zend_class_entry *zend_test_trait;
36 #endif
37 
38 static ZEND_FUNCTION(zend_version);
39 static ZEND_FUNCTION(func_num_args);
40 static ZEND_FUNCTION(func_get_arg);
41 static ZEND_FUNCTION(func_get_args);
42 static ZEND_FUNCTION(strlen);
43 static ZEND_FUNCTION(strcmp);
44 static ZEND_FUNCTION(strncmp);
45 static ZEND_FUNCTION(strcasecmp);
46 static ZEND_FUNCTION(strncasecmp);
47 static ZEND_FUNCTION(each);
48 static ZEND_FUNCTION(error_reporting);
49 static ZEND_FUNCTION(define);
50 static ZEND_FUNCTION(defined);
51 static ZEND_FUNCTION(get_class);
52 static ZEND_FUNCTION(get_called_class);
53 static ZEND_FUNCTION(get_parent_class);
54 static ZEND_FUNCTION(method_exists);
55 static ZEND_FUNCTION(property_exists);
56 static ZEND_FUNCTION(class_exists);
57 static ZEND_FUNCTION(interface_exists);
58 static ZEND_FUNCTION(trait_exists);
59 static ZEND_FUNCTION(function_exists);
60 static ZEND_FUNCTION(class_alias);
61 #if ZEND_DEBUG
62 static ZEND_FUNCTION(leak);
63 static ZEND_FUNCTION(leak_variable);
64 #ifdef ZEND_TEST_EXCEPTIONS
65 static ZEND_FUNCTION(crash);
66 #endif
67 #endif
68 static ZEND_FUNCTION(get_included_files);
69 static ZEND_FUNCTION(is_subclass_of);
70 static ZEND_FUNCTION(is_a);
71 static ZEND_FUNCTION(get_class_vars);
72 static ZEND_FUNCTION(get_object_vars);
73 static ZEND_FUNCTION(get_class_methods);
74 static ZEND_FUNCTION(trigger_error);
75 static ZEND_FUNCTION(set_error_handler);
76 static ZEND_FUNCTION(restore_error_handler);
77 static ZEND_FUNCTION(set_exception_handler);
78 static ZEND_FUNCTION(restore_exception_handler);
79 static ZEND_FUNCTION(get_declared_classes);
80 static ZEND_FUNCTION(get_declared_traits);
81 static ZEND_FUNCTION(get_declared_interfaces);
82 static ZEND_FUNCTION(get_defined_functions);
83 static ZEND_FUNCTION(get_defined_vars);
84 static ZEND_FUNCTION(create_function);
85 static ZEND_FUNCTION(get_resource_type);
86 static ZEND_FUNCTION(get_resources);
87 static ZEND_FUNCTION(get_loaded_extensions);
88 static ZEND_FUNCTION(extension_loaded);
89 static ZEND_FUNCTION(get_extension_funcs);
90 static ZEND_FUNCTION(get_defined_constants);
91 static ZEND_FUNCTION(debug_backtrace);
92 static ZEND_FUNCTION(debug_print_backtrace);
93 #if ZEND_DEBUG
94 static ZEND_FUNCTION(zend_test_func);
95 static ZEND_FUNCTION(zend_test_func2);
96 #ifdef ZTS
97 static ZEND_FUNCTION(zend_thread_id);
98 #endif
99 #endif
100 static ZEND_FUNCTION(gc_mem_caches);
101 static ZEND_FUNCTION(gc_collect_cycles);
102 static ZEND_FUNCTION(gc_enabled);
103 static ZEND_FUNCTION(gc_enable);
104 static ZEND_FUNCTION(gc_disable);
105 
106 /* {{{ arginfo */
107 ZEND_BEGIN_ARG_INFO(arginfo_zend__void, 0)
ZEND_END_ARG_INFO()108 ZEND_END_ARG_INFO()
109 
110 ZEND_BEGIN_ARG_INFO_EX(arginfo_func_get_arg, 0, 0, 1)
111 	ZEND_ARG_INFO(0, arg_num)
112 ZEND_END_ARG_INFO()
113 
114 ZEND_BEGIN_ARG_INFO_EX(arginfo_strlen, 0, 0, 1)
115 	ZEND_ARG_INFO(0, str)
116 ZEND_END_ARG_INFO()
117 
118 ZEND_BEGIN_ARG_INFO_EX(arginfo_strcmp, 0, 0, 2)
119 	ZEND_ARG_INFO(0, str1)
120 	ZEND_ARG_INFO(0, str2)
121 ZEND_END_ARG_INFO()
122 
123 ZEND_BEGIN_ARG_INFO_EX(arginfo_strncmp, 0, 0, 3)
124 	ZEND_ARG_INFO(0, str1)
125 	ZEND_ARG_INFO(0, str2)
126 	ZEND_ARG_INFO(0, len)
127 ZEND_END_ARG_INFO()
128 
129 ZEND_BEGIN_ARG_INFO_EX(arginfo_each, 0, 0, 1)
130 	ZEND_ARG_INFO(1, arr)
131 ZEND_END_ARG_INFO()
132 
133 ZEND_BEGIN_ARG_INFO_EX(arginfo_error_reporting, 0, 0, 0)
134 	ZEND_ARG_INFO(0, new_error_level)
135 ZEND_END_ARG_INFO()
136 
137 ZEND_BEGIN_ARG_INFO_EX(arginfo_define, 0, 0, 2)
138 	ZEND_ARG_INFO(0, constant_name)
139 	ZEND_ARG_INFO(0, value)
140 	ZEND_ARG_INFO(0, case_insensitive)
141 ZEND_END_ARG_INFO()
142 
143 ZEND_BEGIN_ARG_INFO_EX(arginfo_defined, 0, 0, 1)
144 	ZEND_ARG_INFO(0, constant_name)
145 ZEND_END_ARG_INFO()
146 
147 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class, 0, 0, 0)
148 	ZEND_ARG_INFO(0, object)
149 ZEND_END_ARG_INFO()
150 
151 ZEND_BEGIN_ARG_INFO_EX(arginfo_is_subclass_of, 0, 0, 2)
152 	ZEND_ARG_INFO(0, object)
153 	ZEND_ARG_INFO(0, class_name)
154 	ZEND_ARG_INFO(0, allow_string)
155 ZEND_END_ARG_INFO()
156 
157 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_vars, 0, 0, 1)
158 	ZEND_ARG_INFO(0, class_name)
159 ZEND_END_ARG_INFO()
160 
161 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_object_vars, 0, 0, 1)
162 	ZEND_ARG_INFO(0, obj)
163 ZEND_END_ARG_INFO()
164 
165 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_methods, 0, 0, 1)
166 	ZEND_ARG_INFO(0, class)
167 ZEND_END_ARG_INFO()
168 
169 ZEND_BEGIN_ARG_INFO_EX(arginfo_method_exists, 0, 0, 2)
170 	ZEND_ARG_INFO(0, object)
171 	ZEND_ARG_INFO(0, method)
172 ZEND_END_ARG_INFO()
173 
174 ZEND_BEGIN_ARG_INFO_EX(arginfo_property_exists, 0, 0, 2)
175 	ZEND_ARG_INFO(0, object_or_class)
176 	ZEND_ARG_INFO(0, property_name)
177 ZEND_END_ARG_INFO()
178 
179 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_exists, 0, 0, 1)
180 	ZEND_ARG_INFO(0, classname)
181 	ZEND_ARG_INFO(0, autoload)
182 ZEND_END_ARG_INFO()
183 
184 ZEND_BEGIN_ARG_INFO_EX(arginfo_trait_exists, 0, 0, 1)
185 	ZEND_ARG_INFO(0, traitname)
186 	ZEND_ARG_INFO(0, autoload)
187 ZEND_END_ARG_INFO()
188 
189 ZEND_BEGIN_ARG_INFO_EX(arginfo_function_exists, 0, 0, 1)
190 	ZEND_ARG_INFO(0, function_name)
191 ZEND_END_ARG_INFO()
192 
193 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_alias, 0, 0, 2)
194 	ZEND_ARG_INFO(0, user_class_name)
195 	ZEND_ARG_INFO(0, alias_name)
196 	ZEND_ARG_INFO(0, autoload)
197 ZEND_END_ARG_INFO()
198 
199 #if ZEND_DEBUG
200 ZEND_BEGIN_ARG_INFO_EX(arginfo_leak_variable, 0, 0, 1)
201 	ZEND_ARG_INFO(0, variable)
202 	ZEND_ARG_INFO(0, leak_data)
203 ZEND_END_ARG_INFO()
204 #endif
205 
206 ZEND_BEGIN_ARG_INFO_EX(arginfo_trigger_error, 0, 0, 1)
207 	ZEND_ARG_INFO(0, message)
208 	ZEND_ARG_INFO(0, error_type)
209 ZEND_END_ARG_INFO()
210 
211 ZEND_BEGIN_ARG_INFO_EX(arginfo_set_error_handler, 0, 0, 1)
212 	ZEND_ARG_INFO(0, error_handler)
213 	ZEND_ARG_INFO(0, error_types)
214 ZEND_END_ARG_INFO()
215 
216 ZEND_BEGIN_ARG_INFO_EX(arginfo_set_exception_handler, 0, 0, 1)
217 	ZEND_ARG_INFO(0, exception_handler)
218 ZEND_END_ARG_INFO()
219 
220 ZEND_BEGIN_ARG_INFO_EX(arginfo_create_function, 0, 0, 2)
221 	ZEND_ARG_INFO(0, args)
222 	ZEND_ARG_INFO(0, code)
223 ZEND_END_ARG_INFO()
224 
225 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_resource_type, 0, 0, 1)
226 	ZEND_ARG_INFO(0, res)
227 ZEND_END_ARG_INFO()
228 
229 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_resources, 0, 0, 0)
230 	ZEND_ARG_INFO(0, type)
231 ZEND_END_ARG_INFO()
232 
233 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_loaded_extensions, 0, 0, 0)
234 	ZEND_ARG_INFO(0, zend_extensions)
235 ZEND_END_ARG_INFO()
236 
237 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_defined_constants, 0, 0, 0)
238 	ZEND_ARG_INFO(0, categorize)
239 ZEND_END_ARG_INFO()
240 
241 ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_backtrace, 0, 0, 0)
242 	ZEND_ARG_INFO(0, options)
243 	ZEND_ARG_INFO(0, limit)
244 ZEND_END_ARG_INFO()
245 
246 ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_print_backtrace, 0, 0, 0)
247 	ZEND_ARG_INFO(0, options)
248 	ZEND_ARG_INFO(0, limit)
249 ZEND_END_ARG_INFO()
250 
251 ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1)
252 	ZEND_ARG_INFO(0, extension_name)
253 ZEND_END_ARG_INFO()
254 
255 #if ZEND_DEBUG
256 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_zend_test_func, IS_ARRAY, NULL, 0)
257 ZEND_END_ARG_INFO()
258 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_zend_test_func2, IS_ARRAY, NULL, 1)
259 ZEND_END_ARG_INFO()
260 #endif
261 
262 /* }}} */
263 
264 #if ZEND_DEBUG
265 static ZEND_METHOD(_ZendTestTrait, testMethod) /* {{{ */ {
266 	RETURN_TRUE;
267 }
268 /* }}} */
269 
270 static zend_function_entry zend_test_trait_methods[] = {
271     ZEND_ME(_ZendTestTrait, testMethod, arginfo_zend__void, ZEND_ACC_PUBLIC)
272     ZEND_FE_END
273 };
274 #endif
275 
276 static const zend_function_entry builtin_functions[] = { /* {{{ */
277 	ZEND_FE(zend_version,		arginfo_zend__void)
278 	ZEND_FE(func_num_args,		arginfo_zend__void)
279 	ZEND_FE(func_get_arg,		arginfo_func_get_arg)
280 	ZEND_FE(func_get_args,		arginfo_zend__void)
281 	ZEND_FE(strlen,			arginfo_strlen)
282 	ZEND_FE(strcmp,			arginfo_strcmp)
283 	ZEND_FE(strncmp,		arginfo_strncmp)
284 	ZEND_FE(strcasecmp,		arginfo_strcmp)
285 	ZEND_FE(strncasecmp,		arginfo_strncmp)
286 	ZEND_FE(each,			arginfo_each)
287 	ZEND_FE(error_reporting,	arginfo_error_reporting)
288 	ZEND_FE(define,			arginfo_define)
289 	ZEND_FE(defined,		arginfo_defined)
290 	ZEND_FE(get_class,		arginfo_get_class)
291 	ZEND_FE(get_called_class,	arginfo_zend__void)
292 	ZEND_FE(get_parent_class,	arginfo_get_class)
293 	ZEND_FE(method_exists,		arginfo_method_exists)
294 	ZEND_FE(property_exists,	arginfo_property_exists)
295 	ZEND_FE(class_exists,		arginfo_class_exists)
296 	ZEND_FE(interface_exists,	arginfo_class_exists)
297 	ZEND_FE(trait_exists,		arginfo_trait_exists)
298 	ZEND_FE(function_exists,	arginfo_function_exists)
299 	ZEND_FE(class_alias,		arginfo_class_alias)
300 #if ZEND_DEBUG
301 	ZEND_FE(leak,				NULL)
302 	ZEND_FE(leak_variable,		arginfo_leak_variable)
303 #ifdef ZEND_TEST_EXCEPTIONS
304 	ZEND_FE(crash,				NULL)
305 #endif
306 #endif
307 	ZEND_FE(get_included_files,	arginfo_zend__void)
308 	ZEND_FALIAS(get_required_files,	get_included_files,		arginfo_zend__void)
309 	ZEND_FE(is_subclass_of,		arginfo_is_subclass_of)
310 	ZEND_FE(is_a,			arginfo_is_subclass_of)
311 	ZEND_FE(get_class_vars,		arginfo_get_class_vars)
312 	ZEND_FE(get_object_vars,	arginfo_get_object_vars)
313 	ZEND_FE(get_class_methods,	arginfo_get_class_methods)
314 	ZEND_FE(trigger_error,		arginfo_trigger_error)
315 	ZEND_FALIAS(user_error,		trigger_error,		arginfo_trigger_error)
316 	ZEND_FE(set_error_handler,		arginfo_set_error_handler)
317 	ZEND_FE(restore_error_handler,		arginfo_zend__void)
318 	ZEND_FE(set_exception_handler,		arginfo_set_exception_handler)
319 	ZEND_FE(restore_exception_handler,	arginfo_zend__void)
320 	ZEND_FE(get_declared_classes, 		arginfo_zend__void)
321 	ZEND_FE(get_declared_traits, 		arginfo_zend__void)
322 	ZEND_FE(get_declared_interfaces, 	arginfo_zend__void)
323 	ZEND_FE(get_defined_functions, 		arginfo_zend__void)
324 	ZEND_FE(get_defined_vars,		arginfo_zend__void)
325 	ZEND_FE(create_function,		arginfo_create_function)
326 	ZEND_FE(get_resource_type,		arginfo_get_resource_type)
327 	ZEND_FE(get_resources,			arginfo_get_resources)
328 	ZEND_FE(get_loaded_extensions,		arginfo_get_loaded_extensions)
329 	ZEND_FE(extension_loaded,		arginfo_extension_loaded)
330 	ZEND_FE(get_extension_funcs,		arginfo_extension_loaded)
331 	ZEND_FE(get_defined_constants,		arginfo_get_defined_constants)
332 	ZEND_FE(debug_backtrace, 		arginfo_debug_backtrace)
333 	ZEND_FE(debug_print_backtrace, 		arginfo_debug_print_backtrace)
334 #if ZEND_DEBUG
335 	ZEND_FE(zend_test_func,		arginfo_zend_test_func)
336 	ZEND_FE(zend_test_func2,	arginfo_zend_test_func2)
337 #ifdef ZTS
338 	ZEND_FE(zend_thread_id,		NULL)
339 #endif
340 #endif
341 	ZEND_FE(gc_mem_caches,      arginfo_zend__void)
342 	ZEND_FE(gc_collect_cycles, 	arginfo_zend__void)
343 	ZEND_FE(gc_enabled, 		arginfo_zend__void)
344 	ZEND_FE(gc_enable, 		arginfo_zend__void)
345 	ZEND_FE(gc_disable, 		arginfo_zend__void)
346 	ZEND_FE_END
347 };
348 /* }}} */
349 
ZEND_MINIT_FUNCTION(core)350 ZEND_MINIT_FUNCTION(core) { /* {{{ */
351 	zend_class_entry class_entry;
352 
353 	INIT_CLASS_ENTRY(class_entry, "stdClass", NULL);
354 	zend_standard_class_def = zend_register_internal_class(&class_entry);
355 
356 	zend_register_default_classes();
357 
358 #if ZEND_DEBUG
359 	INIT_CLASS_ENTRY(class_entry, "_ZendTestTrait", zend_test_trait_methods);
360 	zend_test_trait = zend_register_internal_class(&class_entry);
361 	zend_test_trait->ce_flags |= ZEND_ACC_TRAIT;
362 	zend_declare_property_null(zend_test_trait, "testProp", sizeof("testProp")-1, ZEND_ACC_PUBLIC);
363 #endif
364 
365 	return SUCCESS;
366 }
367 /* }}} */
368 
369 zend_module_entry zend_builtin_module = { /* {{{ */
370     STANDARD_MODULE_HEADER,
371 	"Core",
372 	builtin_functions,
373 	ZEND_MINIT(core),
374 	NULL,
375 	NULL,
376 	NULL,
377 	NULL,
378 	ZEND_VERSION,
379 	STANDARD_MODULE_PROPERTIES
380 };
381 /* }}} */
382 
zend_startup_builtin_functions(void)383 int zend_startup_builtin_functions(void) /* {{{ */
384 {
385 	zend_builtin_module.module_number = 0;
386 	zend_builtin_module.type = MODULE_PERSISTENT;
387 	return (EG(current_module) = zend_register_module_ex(&zend_builtin_module)) == NULL ? FAILURE : SUCCESS;
388 }
389 /* }}} */
390 
391 /* {{{ proto string zend_version(void)
392    Get the version of the Zend Engine */
ZEND_FUNCTION(zend_version)393 ZEND_FUNCTION(zend_version)
394 {
395 	RETURN_STRINGL(ZEND_VERSION, sizeof(ZEND_VERSION)-1);
396 }
397 /* }}} */
398 
399 /* {{{ proto int gc_mem_caches(void)
400    Reclaims memory used by MM caches.
401    Returns number of freed bytes */
ZEND_FUNCTION(gc_mem_caches)402 ZEND_FUNCTION(gc_mem_caches)
403 {
404 	RETURN_LONG(zend_mm_gc(zend_mm_get_heap()));
405 }
406 /* }}} */
407 
408 /* {{{ proto int gc_collect_cycles(void)
409    Forces collection of any existing garbage cycles.
410    Returns number of freed zvals */
ZEND_FUNCTION(gc_collect_cycles)411 ZEND_FUNCTION(gc_collect_cycles)
412 {
413 	RETURN_LONG(gc_collect_cycles());
414 }
415 /* }}} */
416 
417 /* {{{ proto void gc_enabled(void)
418    Returns status of the circular reference collector */
ZEND_FUNCTION(gc_enabled)419 ZEND_FUNCTION(gc_enabled)
420 {
421 	RETURN_BOOL(GC_G(gc_enabled));
422 }
423 /* }}} */
424 
425 /* {{{ proto void gc_enable(void)
426    Activates the circular reference collector */
ZEND_FUNCTION(gc_enable)427 ZEND_FUNCTION(gc_enable)
428 {
429 	zend_string *key = zend_string_init("zend.enable_gc", sizeof("zend.enable_gc")-1, 0);
430 	zend_alter_ini_entry_chars(key, "1", sizeof("1")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
431 	zend_string_release(key);
432 }
433 /* }}} */
434 
435 /* {{{ proto void gc_disable(void)
436    Deactivates the circular reference collector */
ZEND_FUNCTION(gc_disable)437 ZEND_FUNCTION(gc_disable)
438 {
439 	zend_string *key = zend_string_init("zend.enable_gc", sizeof("zend.enable_gc")-1, 0);
440 	zend_alter_ini_entry_chars(key, "0", sizeof("0")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
441 	zend_string_release(key);
442 }
443 /* }}} */
444 
445 /* {{{ proto int func_num_args(void)
446    Get the number of arguments that were passed to the function */
ZEND_FUNCTION(func_num_args)447 ZEND_FUNCTION(func_num_args)
448 {
449 	zend_execute_data *ex = EX(prev_execute_data);
450 
451 	if (!(ZEND_CALL_INFO(ex) & ZEND_CALL_CODE)) {
452 		RETURN_LONG(ZEND_CALL_NUM_ARGS(ex));
453 	} else {
454 		zend_error(E_WARNING, "func_num_args():  Called from the global scope - no function context");
455 		RETURN_LONG(-1);
456 	}
457 }
458 /* }}} */
459 
460 /* {{{ proto mixed func_get_arg(int arg_num)
461    Get the $arg_num'th argument that was passed to the function */
ZEND_FUNCTION(func_get_arg)462 ZEND_FUNCTION(func_get_arg)
463 {
464 	uint32_t arg_count, first_extra_arg;
465 	zval *arg;
466 	zend_long requested_offset;
467 	zend_execute_data *ex;
468 
469 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &requested_offset) == FAILURE) {
470 		return;
471 	}
472 
473 	if (requested_offset < 0) {
474 		zend_error(E_WARNING, "func_get_arg():  The argument number should be >= 0");
475 		RETURN_FALSE;
476 	}
477 
478 	ex = EX(prev_execute_data);
479 	if (ZEND_CALL_INFO(ex) & ZEND_CALL_CODE) {
480 		zend_error(E_WARNING, "func_get_arg():  Called from the global scope - no function context");
481 		RETURN_FALSE;
482 	}
483 
484 	arg_count = ZEND_CALL_NUM_ARGS(ex);
485 
486 	if (requested_offset >= arg_count) {
487 		zend_error(E_WARNING, "func_get_arg():  Argument " ZEND_LONG_FMT " not passed to function", requested_offset);
488 		RETURN_FALSE;
489 	}
490 
491 	first_extra_arg = ex->func->op_array.num_args;
492 	if (requested_offset >= first_extra_arg && (ZEND_CALL_NUM_ARGS(ex) > first_extra_arg)) {
493 		arg = ZEND_CALL_VAR_NUM(ex, ex->func->op_array.last_var + ex->func->op_array.T) + (requested_offset - first_extra_arg);
494 	} else {
495 		arg = ZEND_CALL_ARG(ex, requested_offset + 1);
496 	}
497 	if (EXPECTED(!Z_ISUNDEF_P(arg))) {
498 		ZVAL_DEREF(arg);
499 		ZVAL_COPY(return_value, arg);
500 	}
501 }
502 /* }}} */
503 
504 /* {{{ proto array func_get_args()
505    Get an array of the arguments that were passed to the function */
ZEND_FUNCTION(func_get_args)506 ZEND_FUNCTION(func_get_args)
507 {
508 	zval *p, *q;
509 	uint32_t arg_count, first_extra_arg;
510 	uint32_t i;
511 	zend_execute_data *ex = EX(prev_execute_data);
512 
513 	if (ZEND_CALL_INFO(ex) & ZEND_CALL_CODE) {
514 		zend_error(E_WARNING, "func_get_args():  Called from the global scope - no function context");
515 		RETURN_FALSE;
516 	}
517 
518 	arg_count = ZEND_CALL_NUM_ARGS(ex);
519 
520 	array_init_size(return_value, arg_count);
521 	if (arg_count) {
522 		first_extra_arg = ex->func->op_array.num_args;
523 		zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
524 		ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
525 			i = 0;
526 			p = ZEND_CALL_ARG(ex, 1);
527 			if (arg_count > first_extra_arg) {
528 				while (i < first_extra_arg) {
529 					q = p;
530 					if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) {
531 						ZVAL_DEREF(q);
532 						if (Z_OPT_REFCOUNTED_P(q)) {
533 							Z_ADDREF_P(q);
534 						}
535 					} else {
536 						q = &EG(uninitialized_zval);
537 					}
538 					ZEND_HASH_FILL_ADD(q);
539 					p++;
540 					i++;
541 				}
542 				p = ZEND_CALL_VAR_NUM(ex, ex->func->op_array.last_var + ex->func->op_array.T);
543 			}
544 			while (i < arg_count) {
545 				q = p;
546 				if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) {
547 					ZVAL_DEREF(q);
548 					if (Z_OPT_REFCOUNTED_P(q)) {
549 						Z_ADDREF_P(q);
550 					}
551 				} else {
552 					q = &EG(uninitialized_zval);
553 				}
554 				ZEND_HASH_FILL_ADD(q);
555 				p++;
556 				i++;
557 			}
558 		} ZEND_HASH_FILL_END();
559 		Z_ARRVAL_P(return_value)->nNumOfElements = arg_count;
560 	}
561 }
562 /* }}} */
563 
564 /* {{{ proto int strlen(string str)
565    Get string length
566    Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
ZEND_FUNCTION(strlen)567 ZEND_FUNCTION(strlen)
568 {
569 	zend_string *s;
570 
571 	ZEND_PARSE_PARAMETERS_START(1, 1)
572 		Z_PARAM_STR(s)
573 	ZEND_PARSE_PARAMETERS_END();
574 
575 	RETVAL_LONG(ZSTR_LEN(s));
576 }
577 /* }}} */
578 
579 /* {{{ proto int strcmp(string str1, string str2)
580    Binary safe string comparison */
ZEND_FUNCTION(strcmp)581 ZEND_FUNCTION(strcmp)
582 {
583 	zend_string *s1, *s2;
584 
585 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &s1, &s2) == FAILURE) {
586 		return;
587 	}
588 
589 	RETURN_LONG(zend_binary_strcmp(ZSTR_VAL(s1), ZSTR_LEN(s1), ZSTR_VAL(s2), ZSTR_LEN(s2)));
590 }
591 /* }}} */
592 
593 /* {{{ proto int strncmp(string str1, string str2, int len)
594    Binary safe string comparison */
ZEND_FUNCTION(strncmp)595 ZEND_FUNCTION(strncmp)
596 {
597 	zend_string *s1, *s2;
598 	zend_long len;
599 
600 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSl", &s1, &s2, &len) == FAILURE) {
601 		return;
602 	}
603 
604 	if (len < 0) {
605 		zend_error(E_WARNING, "Length must be greater than or equal to 0");
606 		RETURN_FALSE;
607 	}
608 
609 	RETURN_LONG(zend_binary_strncmp(ZSTR_VAL(s1), ZSTR_LEN(s1), ZSTR_VAL(s2), ZSTR_LEN(s2), len));
610 }
611 /* }}} */
612 
613 /* {{{ proto int strcasecmp(string str1, string str2)
614    Binary safe case-insensitive string comparison */
ZEND_FUNCTION(strcasecmp)615 ZEND_FUNCTION(strcasecmp)
616 {
617 	zend_string *s1, *s2;
618 
619 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &s1, &s2) == FAILURE) {
620 		return;
621 	}
622 
623 	RETURN_LONG(zend_binary_strcasecmp(ZSTR_VAL(s1), ZSTR_LEN(s1), ZSTR_VAL(s2), ZSTR_LEN(s2)));
624 }
625 /* }}} */
626 
627 /* {{{ proto int strncasecmp(string str1, string str2, int len)
628    Binary safe string comparison */
ZEND_FUNCTION(strncasecmp)629 ZEND_FUNCTION(strncasecmp)
630 {
631 	zend_string *s1, *s2;
632 	zend_long len;
633 
634 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSl", &s1, &s2, &len) == FAILURE) {
635 		return;
636 	}
637 
638 	if (len < 0) {
639 		zend_error(E_WARNING, "Length must be greater than or equal to 0");
640 		RETURN_FALSE;
641 	}
642 
643 	RETURN_LONG(zend_binary_strncasecmp(ZSTR_VAL(s1), ZSTR_LEN(s1), ZSTR_VAL(s2), ZSTR_LEN(s2), len));
644 }
645 /* }}} */
646 
647 /* {{{ proto mixed each(array &arr)
648    Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element, or false if there is no element at this place */
ZEND_FUNCTION(each)649 ZEND_FUNCTION(each)
650 {
651 	zval *array, *entry, tmp;
652 	zend_ulong num_key;
653 	HashTable *target_hash;
654 	zend_string *key;
655 
656 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z/", &array) == FAILURE) {
657 		return;
658 	}
659 
660 	target_hash = HASH_OF(array);
661 	if (!target_hash) {
662 		zend_error(E_WARNING,"Variable passed to each() is not an array or object");
663 		return;
664 	}
665 	while (1) {
666 		entry = zend_hash_get_current_data(target_hash);
667 		if (!entry) {
668 			RETURN_FALSE;
669 		} else if (Z_TYPE_P(entry) == IS_INDIRECT) {
670 			entry = Z_INDIRECT_P(entry);
671 			if (Z_TYPE_P(entry) == IS_UNDEF) {
672 				zend_hash_move_forward(target_hash);
673 				continue;
674 			}
675 		}
676 		break;
677 	}
678 	array_init_size(return_value, 4);
679 	zend_hash_real_init(Z_ARRVAL_P(return_value), 0);
680 
681 	/* add value elements */
682 	if (Z_ISREF_P(entry)) {
683 		ZVAL_DUP(&tmp, Z_REFVAL_P(entry));
684 		entry = &tmp;
685 		if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry);
686 	} else {
687 		if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry);
688 		if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry);
689 	}
690 	zend_hash_index_add_new(Z_ARRVAL_P(return_value), 1, entry);
691 	zend_hash_str_add_new(Z_ARRVAL_P(return_value), "value", sizeof("value")-1, entry);
692 
693 	/* add the key elements */
694 	if (zend_hash_get_current_key(target_hash, &key, &num_key) == HASH_KEY_IS_STRING) {
695 		ZVAL_STR_COPY(&tmp, key);
696 		if (Z_REFCOUNTED(tmp)) Z_ADDREF(tmp);
697 	} else {
698 		ZVAL_LONG(&tmp, num_key);
699 	}
700 	zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp);
701 	zend_hash_str_add_new(Z_ARRVAL_P(return_value), "key", sizeof("key")-1, &tmp);
702 	zend_hash_move_forward(target_hash);
703 }
704 /* }}} */
705 
706 /* {{{ proto int error_reporting([int new_error_level])
707    Return the current error_reporting level, and if an argument was passed - change to the new level */
ZEND_FUNCTION(error_reporting)708 ZEND_FUNCTION(error_reporting)
709 {
710 	zval *err;
711 	int old_error_reporting;
712 
713 	ZEND_PARSE_PARAMETERS_START(0, 1)
714 		Z_PARAM_OPTIONAL
715 		Z_PARAM_ZVAL(err)
716 	ZEND_PARSE_PARAMETERS_END();
717 
718 	old_error_reporting = EG(error_reporting);
719 	if (ZEND_NUM_ARGS() != 0) {
720 		zend_string *new_val = zval_get_string(err);
721 		do {
722 			zend_ini_entry *p = EG(error_reporting_ini_entry);
723 
724 			if (!p) {
725 				p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
726 				if (p) {
727 					EG(error_reporting_ini_entry) = p;
728 				} else {
729 					break;
730 				}
731 			}
732 			if (!p->modified) {
733 				if (!EG(modified_ini_directives)) {
734 					ALLOC_HASHTABLE(EG(modified_ini_directives));
735 					zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
736 				}
737 				if (EXPECTED(zend_hash_str_add_ptr(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting")-1, p) != NULL)) {
738 					p->orig_value = p->value;
739 					p->orig_modifiable = p->modifiable;
740 					p->modified = 1;
741 				}
742 			} else if (p->orig_value != p->value) {
743 				zend_string_release(p->value);
744 			}
745 
746 			p->value = new_val;
747 			if (Z_TYPE_P(err) == IS_LONG) {
748 				EG(error_reporting) = Z_LVAL_P(err);
749 			} else {
750 				EG(error_reporting) = atoi(ZSTR_VAL(p->value));
751 			}
752 		} while (0);
753 	}
754 
755 	RETVAL_LONG(old_error_reporting);
756 }
757 /* }}} */
758 
validate_constant_array(HashTable * ht)759 static int validate_constant_array(HashTable *ht) /* {{{ */
760 {
761 	int ret = 1;
762 	zval *val;
763 
764 	ht->u.v.nApplyCount++;
765 	ZEND_HASH_FOREACH_VAL_IND(ht, val) {
766 		ZVAL_DEREF(val);
767 		if (Z_REFCOUNTED_P(val)) {
768 			if (Z_TYPE_P(val) == IS_ARRAY) {
769 				if (!Z_IMMUTABLE_P(val)) {
770 					if (Z_ARRVAL_P(val)->u.v.nApplyCount > 0) {
771 						zend_error(E_WARNING, "Constants cannot be recursive arrays");
772 						ret = 0;
773 						break;
774 					} else if (!validate_constant_array(Z_ARRVAL_P(val))) {
775 						ret = 0;
776 						break;
777 					}
778 				}
779 			} else if (Z_TYPE_P(val) != IS_STRING && Z_TYPE_P(val) != IS_RESOURCE) {
780 				zend_error(E_WARNING, "Constants may only evaluate to scalar values or arrays");
781 				ret = 0;
782 				break;
783 			}
784 		}
785 	} ZEND_HASH_FOREACH_END();
786 	ht->u.v.nApplyCount--;
787 	return ret;
788 }
789 /* }}} */
790 
copy_constant_array(zval * dst,zval * src)791 static void copy_constant_array(zval *dst, zval *src) /* {{{ */
792 {
793 	zend_string *key;
794 	zend_ulong idx;
795 	zval *new_val, *val;
796 
797 	array_init_size(dst, zend_hash_num_elements(Z_ARRVAL_P(src)));
798 	ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(src), idx, key, val) {
799 		/* constant arrays can't contain references */
800 		ZVAL_DEREF(val);
801 		if (key) {
802 			new_val = zend_hash_add_new(Z_ARRVAL_P(dst), key, val);
803 		} else {
804 			new_val = zend_hash_index_add_new(Z_ARRVAL_P(dst), idx, val);
805 		}
806 		if (Z_TYPE_P(val) == IS_ARRAY) {
807 			if (!Z_IMMUTABLE_P(val)) {
808 				copy_constant_array(new_val, val);
809 			}
810 		} else if (Z_REFCOUNTED_P(val)) {
811 			Z_ADDREF_P(val);
812 		}
813 	} ZEND_HASH_FOREACH_END();
814 }
815 /* }}} */
816 
817 /* {{{ proto bool define(string constant_name, mixed value[, boolean case_insensitive])
818    Define a new constant */
ZEND_FUNCTION(define)819 ZEND_FUNCTION(define)
820 {
821 	zend_string *name;
822 	zval *val, val_free;
823 	zend_bool non_cs = 0;
824 	int case_sensitive = CONST_CS;
825 	zend_constant c;
826 
827 	ZEND_PARSE_PARAMETERS_START(2, 3)
828 		Z_PARAM_STR(name)
829 		Z_PARAM_ZVAL(val)
830 		Z_PARAM_OPTIONAL
831 		Z_PARAM_BOOL(non_cs)
832 	ZEND_PARSE_PARAMETERS_END();
833 
834 	if (non_cs) {
835 		case_sensitive = 0;
836 	}
837 
838 	/* class constant, check if there is name and make sure class is valid & exists */
839 	if (zend_memnstr(ZSTR_VAL(name), "::", sizeof("::") - 1, ZSTR_VAL(name) + ZSTR_LEN(name))) {
840 		zend_error(E_WARNING, "Class constants cannot be defined or redefined");
841 		RETURN_FALSE;
842 	}
843 
844 	ZVAL_UNDEF(&val_free);
845 
846 repeat:
847 	switch (Z_TYPE_P(val)) {
848 		case IS_LONG:
849 		case IS_DOUBLE:
850 		case IS_STRING:
851 		case IS_FALSE:
852 		case IS_TRUE:
853 		case IS_NULL:
854 		case IS_RESOURCE:
855 			break;
856 		case IS_ARRAY:
857 			if (!Z_IMMUTABLE_P(val)) {
858 				if (!validate_constant_array(Z_ARRVAL_P(val))) {
859 					RETURN_FALSE;
860 				} else {
861 					copy_constant_array(&c.value, val);
862 					goto register_constant;
863 				}
864 			}
865 			break;
866 		case IS_OBJECT:
867 			if (Z_TYPE(val_free) == IS_UNDEF) {
868 				if (Z_OBJ_HT_P(val)->get) {
869 					zval rv;
870 					val = Z_OBJ_HT_P(val)->get(val, &rv);
871 					ZVAL_COPY_VALUE(&val_free, val);
872 					goto repeat;
873 				} else if (Z_OBJ_HT_P(val)->cast_object) {
874 					if (Z_OBJ_HT_P(val)->cast_object(val, &val_free, IS_STRING) == SUCCESS) {
875 						val = &val_free;
876 						break;
877 					}
878 				}
879 			}
880 			/* no break */
881 		default:
882 			zend_error(E_WARNING, "Constants may only evaluate to scalar values or arrays");
883 			zval_ptr_dtor(&val_free);
884 			RETURN_FALSE;
885 	}
886 
887 	ZVAL_DUP(&c.value, val);
888 	zval_ptr_dtor(&val_free);
889 register_constant:
890 	c.flags = case_sensitive; /* non persistent */
891 	c.name = zend_string_copy(name);
892 	c.module_number = PHP_USER_CONSTANT;
893 	if (zend_register_constant(&c) == SUCCESS) {
894 		RETURN_TRUE;
895 	} else {
896 		RETURN_FALSE;
897 	}
898 }
899 /* }}} */
900 
901 /* {{{ proto bool defined(string constant_name)
902    Check whether a constant exists
903    Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
ZEND_FUNCTION(defined)904 ZEND_FUNCTION(defined)
905 {
906 	zend_string *name;
907 
908 	ZEND_PARSE_PARAMETERS_START(1, 1)
909 		Z_PARAM_STR(name)
910 	ZEND_PARSE_PARAMETERS_END();
911 
912 	if (zend_get_constant_ex(name, NULL, ZEND_FETCH_CLASS_SILENT)) {
913 		RETURN_TRUE;
914 	} else {
915 		RETURN_FALSE;
916 	}
917 }
918 /* }}} */
919 
920 /* {{{ proto string get_class([object object])
921    Retrieves the class name */
ZEND_FUNCTION(get_class)922 ZEND_FUNCTION(get_class)
923 {
924 	zval *obj = NULL;
925 
926 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|o!", &obj) == FAILURE) {
927 		RETURN_FALSE;
928 	}
929 
930 	if (!obj) {
931 		if (EG(scope)) {
932 			RETURN_STR_COPY(EG(scope)->name);
933 		} else {
934 			zend_error(E_WARNING, "get_class() called without object from outside a class");
935 			RETURN_FALSE;
936 		}
937 	}
938 
939 	RETURN_STR_COPY(Z_OBJCE_P(obj)->name);
940 }
941 /* }}} */
942 
943 /* {{{ proto string get_called_class()
944    Retrieves the "Late Static Binding" class name */
ZEND_FUNCTION(get_called_class)945 ZEND_FUNCTION(get_called_class)
946 {
947 	zend_class_entry *called_scope;
948 
949 	if (zend_parse_parameters_none() == FAILURE) {
950 		return;
951 	}
952 
953 	called_scope = zend_get_called_scope(execute_data);
954 	if (called_scope) {
955 		RETURN_STR_COPY(called_scope->name);
956 	} else if (!EG(scope))  {
957 		zend_error(E_WARNING, "get_called_class() called from outside a class");
958 	}
959 	RETURN_FALSE;
960 }
961 /* }}} */
962 
963 /* {{{ proto mixed get_parent_class([mixed object])
964    Retrieves the parent class name for object or class or current scope or false if not in a scope. */
ZEND_FUNCTION(get_parent_class)965 ZEND_FUNCTION(get_parent_class)
966 {
967 	zval *arg;
968 	zend_class_entry *ce = NULL;
969 
970 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|z", &arg) == FAILURE) {
971 		return;
972 	}
973 
974 	if (!ZEND_NUM_ARGS()) {
975 		ce = EG(scope);
976 		if (ce && ce->parent) {
977 			RETURN_STR_COPY(ce->parent->name);
978 		} else {
979 			RETURN_FALSE;
980 		}
981 	}
982 
983 	if (Z_TYPE_P(arg) == IS_OBJECT) {
984 		ce = Z_OBJ_P(arg)->ce;
985 	} else if (Z_TYPE_P(arg) == IS_STRING) {
986 	    ce = zend_lookup_class(Z_STR_P(arg));
987 	}
988 
989 	if (ce && ce->parent) {
990 		RETURN_STR_COPY(ce->parent->name);
991 	} else {
992 		RETURN_FALSE;
993 	}
994 }
995 /* }}} */
996 
is_a_impl(INTERNAL_FUNCTION_PARAMETERS,zend_bool only_subclass)997 static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass) /* {{{ */
998 {
999 	zval *obj;
1000 	zend_string *class_name;
1001 	zend_class_entry *instance_ce;
1002 	zend_class_entry *ce;
1003 	zend_bool allow_string = only_subclass;
1004 	zend_bool retval;
1005 
1006 	ZEND_PARSE_PARAMETERS_START(2, 3)
1007 		Z_PARAM_ZVAL(obj)
1008 		Z_PARAM_STR(class_name)
1009 		Z_PARAM_OPTIONAL
1010 		Z_PARAM_BOOL(allow_string)
1011 	ZEND_PARSE_PARAMETERS_END();
1012 	/*
1013 	 * allow_string - is_a default is no, is_subclass_of is yes.
1014 	 *   if it's allowed, then the autoloader will be called if the class does not exist.
1015 	 *   default behaviour is different, as 'is_a' used to be used to test mixed return values
1016 	 *   and there is no easy way to deprecate this.
1017 	 */
1018 
1019 	if (allow_string && Z_TYPE_P(obj) == IS_STRING) {
1020 		instance_ce = zend_lookup_class(Z_STR_P(obj));
1021 		if (!instance_ce) {
1022 			RETURN_FALSE;
1023 		}
1024 	} else if (Z_TYPE_P(obj) == IS_OBJECT) {
1025 		instance_ce = Z_OBJCE_P(obj);
1026 	} else {
1027 		RETURN_FALSE;
1028 	}
1029 
1030 	if (!only_subclass && EXPECTED(zend_string_equals(instance_ce->name, class_name))) {
1031 		retval = 1;
1032 	} else {
1033 		ce = zend_lookup_class_ex(class_name, NULL, 0);
1034 		if (!ce) {
1035 			retval = 0;
1036 		} else {
1037 			if (only_subclass && instance_ce == ce) {
1038 				retval = 0;
1039 			} else {
1040 				retval = instanceof_function(instance_ce, ce);
1041 			}
1042 		}
1043 	}
1044 
1045 	RETURN_BOOL(retval);
1046 }
1047 /* }}} */
1048 
1049 /* {{{ proto bool is_subclass_of(mixed object_or_string, string class_name [, bool allow_string])
1050    Returns true if the object has this class as one of its parents */
ZEND_FUNCTION(is_subclass_of)1051 ZEND_FUNCTION(is_subclass_of)
1052 {
1053 	is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1054 }
1055 /* }}} */
1056 
1057 /* {{{ proto bool is_a(mixed object_or_string, string class_name [, bool allow_string])
1058    Returns true if the first argument is an object and is this class or has this class as one of its parents, */
ZEND_FUNCTION(is_a)1059 ZEND_FUNCTION(is_a)
1060 {
1061 	is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1062 }
1063 /* }}} */
1064 
1065 /* {{{ add_class_vars */
add_class_vars(zend_class_entry * ce,int statics,zval * return_value)1066 static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value)
1067 {
1068 	zend_property_info *prop_info;
1069 	zval *prop, prop_copy;
1070 	zend_string *key;
1071 
1072 	ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
1073 		if (((prop_info->flags & ZEND_ACC_SHADOW) &&
1074 		     prop_info->ce != EG(scope)) ||
1075 		    ((prop_info->flags & ZEND_ACC_PROTECTED) &&
1076 		     !zend_check_protected(prop_info->ce, EG(scope))) ||
1077 		    ((prop_info->flags & ZEND_ACC_PRIVATE) &&
1078 		      ce != EG(scope) &&
1079 			  prop_info->ce != EG(scope))) {
1080 			continue;
1081 		}
1082 		prop = NULL;
1083 		if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
1084 			prop = &ce->default_static_members_table[prop_info->offset];
1085 		} else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
1086 			prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
1087 		}
1088 		if (!prop || Z_TYPE_P(prop) == IS_UNDEF) {
1089 			continue;
1090 		}
1091 
1092 		/* copy: enforce read only access */
1093 		ZVAL_DEREF(prop);
1094 		if (UNEXPECTED(Z_COPYABLE_P(prop))) {
1095 			ZVAL_DUP(&prop_copy, prop);
1096 			prop = &prop_copy;
1097 		} else {
1098 			Z_TRY_ADDREF_P(prop);
1099 		}
1100 
1101 		/* this is necessary to make it able to work with default array
1102 		 * properties, returned to user */
1103 		if (Z_OPT_CONSTANT_P(prop)) {
1104 			if (UNEXPECTED(zval_update_constant_ex(prop, 0, NULL) != SUCCESS)) {
1105 				return;
1106 			}
1107 		}
1108 
1109 		zend_hash_add_new(Z_ARRVAL_P(return_value), key, prop);
1110 	} ZEND_HASH_FOREACH_END();
1111 }
1112 /* }}} */
1113 
1114 /* {{{ proto array get_class_vars(string class_name)
1115    Returns an array of default properties of the class. */
ZEND_FUNCTION(get_class_vars)1116 ZEND_FUNCTION(get_class_vars)
1117 {
1118 	zend_string *class_name;
1119 	zend_class_entry *ce;
1120 
1121 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &class_name) == FAILURE) {
1122 		return;
1123 	}
1124 
1125 	ce = zend_lookup_class(class_name);
1126 	if (!ce) {
1127 		RETURN_FALSE;
1128 	} else {
1129 		array_init(return_value);
1130 		if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
1131 			if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
1132 				return;
1133 			}
1134 		}
1135 		add_class_vars(ce, 0, return_value);
1136 		add_class_vars(ce, 1, return_value);
1137 	}
1138 }
1139 /* }}} */
1140 
1141 /* {{{ proto array get_object_vars(object obj)
1142    Returns an array of object properties */
ZEND_FUNCTION(get_object_vars)1143 ZEND_FUNCTION(get_object_vars)
1144 {
1145 	zval *obj;
1146 	zval *value;
1147 	HashTable *properties;
1148 	zend_string *key;
1149 	zend_object *zobj;
1150 	zend_ulong index;
1151 	zend_bool fast_copy = 0;
1152 
1153 	ZEND_PARSE_PARAMETERS_START(1, 1)
1154 		Z_PARAM_OBJECT(obj)
1155 	ZEND_PARSE_PARAMETERS_END();
1156 
1157 	if (Z_OBJ_HT_P(obj)->get_properties == NULL) {
1158 		RETURN_FALSE;
1159 	}
1160 
1161 	properties = Z_OBJ_HT_P(obj)->get_properties(obj);
1162 
1163 	if (properties == NULL) {
1164 		RETURN_FALSE;
1165 	}
1166 
1167 	zobj = Z_OBJ_P(obj);
1168 
1169 	if (!zobj->ce->default_properties_count && properties == zobj->properties && !ZEND_HASH_GET_APPLY_COUNT(properties)) {
1170 		fast_copy = 1;
1171 		/* Check if the object has a numeric property, See Bug 73998 */
1172 		ZEND_HASH_FOREACH_STR_KEY(properties, key) {
1173 			if (key && ZEND_HANDLE_NUMERIC(key, index)) {
1174 				fast_copy = 0;
1175 				break;
1176 			}
1177 		} ZEND_HASH_FOREACH_END();
1178 	}
1179 
1180 	if (fast_copy) {
1181 		if (EXPECTED(zobj->handlers == &std_object_handlers)) {
1182 			if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
1183 				GC_REFCOUNT(properties)++;
1184 			}
1185 			RETURN_ARR(properties);
1186 		}
1187 		RETURN_ARR(zend_array_dup(properties));
1188 	} else {
1189 		array_init_size(return_value, zend_hash_num_elements(properties));
1190 
1191 		ZEND_HASH_FOREACH_STR_KEY_VAL_IND(properties, key, value) {
1192 			if (key) {
1193 				if (zend_check_property_access(zobj, key) == SUCCESS) {
1194 					if (Z_ISREF_P(value) && Z_REFCOUNT_P(value) == 1) {
1195 						value = Z_REFVAL_P(value);
1196 					}
1197 					if (Z_REFCOUNTED_P(value)) {
1198 						Z_ADDREF_P(value);
1199 					}
1200 					if (ZSTR_VAL(key)[0] == 0) {
1201 						const char *prop_name, *class_name;
1202 						size_t prop_len;
1203 						zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_len);
1204 						zend_hash_str_add_new(Z_ARRVAL_P(return_value), prop_name, prop_len, value);
1205 					} else {
1206 						zend_symtable_add_new(Z_ARRVAL_P(return_value), key, value);
1207 					}
1208 				}
1209 			}
1210 		} ZEND_HASH_FOREACH_END();
1211 	}
1212 }
1213 /* }}} */
1214 
same_name(zend_string * key,zend_string * name)1215 static int same_name(zend_string *key, zend_string *name) /* {{{ */
1216 {
1217 	zend_string *lcname;
1218 	int ret;
1219 
1220 	if (key == name) {
1221 		return 1;
1222 	}
1223 	if (ZSTR_LEN(key) != ZSTR_LEN(name)) {
1224 		return 0;
1225 	}
1226 	lcname = zend_string_tolower(name);
1227 	ret = memcmp(ZSTR_VAL(lcname), ZSTR_VAL(key), ZSTR_LEN(key)) == 0;
1228 	zend_string_release(lcname);
1229 	return ret;
1230 }
1231 /* }}} */
1232 
1233 /* {{{ proto array get_class_methods(mixed class)
1234    Returns an array of method names for class or class instance. */
ZEND_FUNCTION(get_class_methods)1235 ZEND_FUNCTION(get_class_methods)
1236 {
1237 	zval *klass;
1238 	zval method_name;
1239 	zend_class_entry *ce = NULL;
1240 	zend_function *mptr;
1241 	zend_string *key;
1242 
1243 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &klass) == FAILURE) {
1244 		return;
1245 	}
1246 
1247 	if (Z_TYPE_P(klass) == IS_OBJECT) {
1248 		ce = Z_OBJCE_P(klass);
1249 	} else if (Z_TYPE_P(klass) == IS_STRING) {
1250 	    ce = zend_lookup_class(Z_STR_P(klass));
1251 	}
1252 
1253 	if (!ce) {
1254 		RETURN_NULL();
1255 	}
1256 
1257 	array_init(return_value);
1258 
1259 	ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, key, mptr) {
1260 
1261 		if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC)
1262 		 || (EG(scope) &&
1263 		     (((mptr->common.fn_flags & ZEND_ACC_PROTECTED) &&
1264 		       zend_check_protected(mptr->common.scope, EG(scope)))
1265 		   || ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
1266 		       EG(scope) == mptr->common.scope)))) {
1267 			size_t len = ZSTR_LEN(mptr->common.function_name);
1268 
1269 			/* Do not display old-style inherited constructors */
1270 			if (!key) {
1271 				ZVAL_STR_COPY(&method_name, mptr->common.function_name);
1272 				zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name);
1273 			} else if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 ||
1274 			    mptr->common.scope == ce ||
1275 			    zend_binary_strcasecmp(ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(mptr->common.function_name), len) == 0) {
1276 
1277 				if (mptr->type == ZEND_USER_FUNCTION &&
1278 				    (!mptr->op_array.refcount || *mptr->op_array.refcount > 1) &&
1279 			    	 !same_name(key, mptr->common.function_name)) {
1280 					ZVAL_STR_COPY(&method_name, zend_find_alias_name(mptr->common.scope, key));
1281 					zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name);
1282 				} else {
1283 					ZVAL_STR_COPY(&method_name, mptr->common.function_name);
1284 					zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name);
1285 				}
1286 			}
1287 		}
1288 	} ZEND_HASH_FOREACH_END();
1289 }
1290 /* }}} */
1291 
1292 /* {{{ proto bool method_exists(object object, string method)
1293    Checks if the class method exists */
ZEND_FUNCTION(method_exists)1294 ZEND_FUNCTION(method_exists)
1295 {
1296 	zval *klass;
1297 	zend_string *method_name;
1298 	zend_string *lcname;
1299 	zend_class_entry * ce;
1300 
1301 	ZEND_PARSE_PARAMETERS_START(2, 2)
1302 		Z_PARAM_ZVAL(klass)
1303 		Z_PARAM_STR(method_name)
1304 	ZEND_PARSE_PARAMETERS_END();
1305 
1306 	if (Z_TYPE_P(klass) == IS_OBJECT) {
1307 		ce = Z_OBJCE_P(klass);
1308 	} else if (Z_TYPE_P(klass) == IS_STRING) {
1309 		if ((ce = zend_lookup_class(Z_STR_P(klass))) == NULL) {
1310 			RETURN_FALSE;
1311 		}
1312 	} else {
1313 		RETURN_FALSE;
1314 	}
1315 
1316 	lcname = zend_string_tolower(method_name);
1317 	if (zend_hash_exists(&ce->function_table, lcname)) {
1318 		zend_string_release(lcname);
1319 		RETURN_TRUE;
1320 	} else {
1321 		union _zend_function *func = NULL;
1322 
1323 		if (Z_TYPE_P(klass) == IS_OBJECT
1324 		&& Z_OBJ_HT_P(klass)->get_method != NULL
1325 		&& (func = Z_OBJ_HT_P(klass)->get_method(&Z_OBJ_P(klass), method_name, NULL)) != NULL
1326 		) {
1327 			if (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
1328 				/* Returns true to the fake Closure's __invoke */
1329 				RETVAL_BOOL(func->common.scope == zend_ce_closure
1330 					&& zend_string_equals_literal(method_name, ZEND_INVOKE_FUNC_NAME));
1331 
1332 				zend_string_release(lcname);
1333 				zend_string_release(func->common.function_name);
1334 				zend_free_trampoline(func);
1335 				return;
1336 			}
1337 			zend_string_release(lcname);
1338 			RETURN_TRUE;
1339 		}
1340 	}
1341 	zend_string_release(lcname);
1342 	RETURN_FALSE;
1343 }
1344 /* }}} */
1345 
1346 /* {{{ proto bool property_exists(mixed object_or_class, string property_name)
1347    Checks if the object or class has a property */
ZEND_FUNCTION(property_exists)1348 ZEND_FUNCTION(property_exists)
1349 {
1350 	zval *object;
1351 	zend_string *property;
1352 	zend_class_entry *ce;
1353 	zend_property_info *property_info;
1354 	zval property_z;
1355 
1356 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "zS", &object, &property) == FAILURE) {
1357 		return;
1358 	}
1359 
1360 	if (property == NULL) {
1361 		RETURN_FALSE;
1362 	}
1363 
1364 	if (Z_TYPE_P(object) == IS_STRING) {
1365 		ce = zend_lookup_class(Z_STR_P(object));
1366 		if (!ce) {
1367 			RETURN_FALSE;
1368 		}
1369 	} else if (Z_TYPE_P(object) == IS_OBJECT) {
1370 		ce = Z_OBJCE_P(object);
1371 	} else {
1372 		zend_error(E_WARNING, "First parameter must either be an object or the name of an existing class");
1373 		RETURN_NULL();
1374 	}
1375 
1376 	if ((property_info = zend_hash_find_ptr(&ce->properties_info, property)) != NULL
1377 		&& (property_info->flags & ZEND_ACC_SHADOW) == 0) {
1378 		RETURN_TRUE;
1379 	}
1380 
1381 	ZVAL_STR(&property_z, property);
1382 
1383 	if (Z_TYPE_P(object) ==  IS_OBJECT &&
1384 		Z_OBJ_HANDLER_P(object, has_property) &&
1385 		Z_OBJ_HANDLER_P(object, has_property)(object, &property_z, 2, NULL)) {
1386 		RETURN_TRUE;
1387 	}
1388 	RETURN_FALSE;
1389 }
1390 /* }}} */
1391 
1392 /* {{{ proto bool class_exists(string classname [, bool autoload])
1393    Checks if the class exists */
ZEND_FUNCTION(class_exists)1394 ZEND_FUNCTION(class_exists)
1395 {
1396 	zend_string *class_name;
1397 	zend_string *lc_name;
1398 	zend_class_entry *ce;
1399 	zend_bool autoload = 1;
1400 
1401 	ZEND_PARSE_PARAMETERS_START(1, 2)
1402 		Z_PARAM_STR(class_name)
1403 		Z_PARAM_OPTIONAL
1404 		Z_PARAM_BOOL(autoload)
1405 	ZEND_PARSE_PARAMETERS_END();
1406 
1407 	if (!autoload) {
1408 		if (ZSTR_VAL(class_name)[0] == '\\') {
1409 			/* Ignore leading "\" */
1410 			lc_name = zend_string_alloc(ZSTR_LEN(class_name) - 1, 0);
1411 			zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(class_name) + 1, ZSTR_LEN(class_name) - 1);
1412 		} else {
1413 			lc_name = zend_string_tolower(class_name);
1414 		}
1415 
1416 		ce = zend_hash_find_ptr(EG(class_table), lc_name);
1417 		zend_string_release(lc_name);
1418 	} else {
1419 		ce = zend_lookup_class(class_name);
1420 	}
1421 
1422  	if (ce) {
1423  		RETURN_BOOL((ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) == 0);
1424 	} else {
1425 		RETURN_FALSE;
1426 	}
1427 }
1428 /* }}} */
1429 
1430 /* {{{ proto bool interface_exists(string classname [, bool autoload])
1431    Checks if the class exists */
ZEND_FUNCTION(interface_exists)1432 ZEND_FUNCTION(interface_exists)
1433 {
1434 	zend_string *iface_name, *lc_name;
1435 	zend_class_entry *ce;
1436 	zend_bool autoload = 1;
1437 
1438 	ZEND_PARSE_PARAMETERS_START(1, 2)
1439 		Z_PARAM_STR(iface_name)
1440 		Z_PARAM_OPTIONAL
1441 		Z_PARAM_BOOL(autoload)
1442 	ZEND_PARSE_PARAMETERS_END();
1443 
1444 	if (!autoload) {
1445 		if (ZSTR_VAL(iface_name)[0] == '\\') {
1446 			/* Ignore leading "\" */
1447 			lc_name = zend_string_alloc(ZSTR_LEN(iface_name) - 1, 0);
1448 			zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(iface_name) + 1, ZSTR_LEN(iface_name) - 1);
1449 		} else {
1450 			lc_name = zend_string_tolower(iface_name);
1451 		}
1452 		ce = zend_hash_find_ptr(EG(class_table), lc_name);
1453 		zend_string_release(lc_name);
1454 		RETURN_BOOL(ce && ce->ce_flags & ZEND_ACC_INTERFACE);
1455 	}
1456 
1457 	ce = zend_lookup_class(iface_name);
1458 	if (ce) {
1459  		RETURN_BOOL((ce->ce_flags & ZEND_ACC_INTERFACE) > 0);
1460 	} else {
1461 		RETURN_FALSE;
1462 	}
1463 }
1464 /* }}} */
1465 
1466 /* {{{ proto bool trait_exists(string traitname [, bool autoload])
1467  Checks if the trait exists */
ZEND_FUNCTION(trait_exists)1468 ZEND_FUNCTION(trait_exists)
1469 {
1470 	zend_string *trait_name, *lc_name;
1471 	zend_class_entry *ce;
1472 	zend_bool autoload = 1;
1473 
1474 	ZEND_PARSE_PARAMETERS_START(1, 2)
1475 		Z_PARAM_STR(trait_name)
1476 		Z_PARAM_OPTIONAL
1477 		Z_PARAM_BOOL(autoload)
1478 	ZEND_PARSE_PARAMETERS_END();
1479 
1480 	if (!autoload) {
1481 		if (ZSTR_VAL(trait_name)[0] == '\\') {
1482 			/* Ignore leading "\" */
1483 			lc_name = zend_string_alloc(ZSTR_LEN(trait_name) - 1, 0);
1484 			zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(trait_name) + 1, ZSTR_LEN(trait_name) - 1);
1485 		} else {
1486 			lc_name = zend_string_tolower(trait_name);
1487 		}
1488 
1489 		ce = zend_hash_find_ptr(EG(class_table), lc_name);
1490 		zend_string_release(lc_name);
1491 	} else {
1492 		ce = zend_lookup_class(trait_name);
1493 	}
1494 
1495 	if (ce) {
1496  		RETURN_BOOL((ce->ce_flags & ZEND_ACC_TRAIT) != 0);
1497 	} else {
1498 		RETURN_FALSE;
1499 	}
1500 }
1501 /* }}} */
1502 
1503 /* {{{ proto bool function_exists(string function_name)
1504    Checks if the function exists */
ZEND_FUNCTION(function_exists)1505 ZEND_FUNCTION(function_exists)
1506 {
1507 	zend_string *name;
1508 	zend_function *func;
1509 	zend_string *lcname;
1510 
1511 	ZEND_PARSE_PARAMETERS_START(1, 1)
1512 		Z_PARAM_STR(name)
1513 	ZEND_PARSE_PARAMETERS_END();
1514 
1515 	if (ZSTR_VAL(name)[0] == '\\') {
1516 		/* Ignore leading "\" */
1517 		lcname = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
1518 		zend_str_tolower_copy(ZSTR_VAL(lcname), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
1519 	} else {
1520 		lcname = zend_string_tolower(name);
1521 	}
1522 
1523 	func = zend_hash_find_ptr(EG(function_table), lcname);
1524 	zend_string_release(lcname);
1525 
1526 	/*
1527 	 * A bit of a hack, but not a bad one: we see if the handler of the function
1528 	 * is actually one that displays "function is disabled" message.
1529 	 */
1530 	RETURN_BOOL(func && (func->type != ZEND_INTERNAL_FUNCTION ||
1531 		func->internal_function.handler != zif_display_disabled_function));
1532 }
1533 /* }}} */
1534 
1535 /* {{{ proto bool class_alias(string user_class_name , string alias_name [, bool autoload])
1536    Creates an alias for user defined class */
ZEND_FUNCTION(class_alias)1537 ZEND_FUNCTION(class_alias)
1538 {
1539 	zend_string *class_name;
1540 	char *alias_name;
1541 	zend_class_entry *ce;
1542 	size_t alias_name_len;
1543 	zend_bool autoload = 1;
1544 
1545 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ss|b", &class_name, &alias_name, &alias_name_len, &autoload) == FAILURE) {
1546 		return;
1547 	}
1548 
1549 	ce = zend_lookup_class_ex(class_name, NULL, autoload);
1550 
1551 	if (ce) {
1552 		if (ce->type == ZEND_USER_CLASS) {
1553 			if (zend_register_class_alias_ex(alias_name, alias_name_len, ce) == SUCCESS) {
1554 				RETURN_TRUE;
1555 			} else {
1556 				zend_error(E_WARNING, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), alias_name);
1557 				RETURN_FALSE;
1558 			}
1559 		} else {
1560 			zend_error(E_WARNING, "First argument of class_alias() must be a name of user defined class");
1561 			RETURN_FALSE;
1562 		}
1563 	} else {
1564 		zend_error(E_WARNING, "Class '%s' not found", ZSTR_VAL(class_name));
1565 		RETURN_FALSE;
1566 	}
1567 }
1568 /* }}} */
1569 
1570 #if ZEND_DEBUG
1571 /* {{{ proto void leak([int num_bytes])
1572    Cause an intentional memory leak, for testing/debugging purposes */
ZEND_FUNCTION(leak)1573 ZEND_FUNCTION(leak)
1574 {
1575 	zend_long leakbytes = 3;
1576 
1577 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &leakbytes) == FAILURE) {
1578 		return;
1579 	}
1580 
1581 	emalloc(leakbytes);
1582 }
1583 /* }}} */
1584 
1585 /* {{{ proto void leak_variable(mixed variable [, bool leak_data])
1586    Leak a variable that is a resource or an object */
ZEND_FUNCTION(leak_variable)1587 ZEND_FUNCTION(leak_variable)
1588 {
1589 	zval *zv;
1590 	zend_bool leak_data = 0;
1591 
1592 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &zv, &leak_data) == FAILURE) {
1593 		return;
1594 	}
1595 
1596 	if (!leak_data) {
1597 		Z_ADDREF_P(zv);
1598 	} else if (Z_TYPE_P(zv) == IS_RESOURCE) {
1599 		Z_ADDREF_P(zv);
1600 	} else if (Z_TYPE_P(zv) == IS_OBJECT) {
1601 		Z_ADDREF_P(zv);
1602 	} else {
1603 		zend_error(E_WARNING, "Leaking non-zval data is only applicable to resources and objects");
1604 	}
1605 }
1606 /* }}} */
1607 
1608 
1609 #ifdef ZEND_TEST_EXCEPTIONS
1610 /* {{{ proto void crash(void)
1611    Crash the script */
ZEND_FUNCTION(crash)1612 ZEND_FUNCTION(crash)
1613 {
1614 	char *nowhere = NULL;
1615 
1616 	if (zend_parse_parameters_none() == FAILURE) {
1617 		return;
1618 	}
1619 
1620 	memcpy(nowhere, "something", sizeof("something"));
1621 }
1622 /* }}} */
1623 #endif
1624 
1625 #endif /* ZEND_DEBUG */
1626 
1627 /* {{{ proto array get_included_files(void)
1628    Returns an array with the file names that were include_once()'d */
ZEND_FUNCTION(get_included_files)1629 ZEND_FUNCTION(get_included_files)
1630 {
1631 	zend_string *entry;
1632 
1633 	if (zend_parse_parameters_none() == FAILURE) {
1634 		return;
1635 	}
1636 
1637 	array_init(return_value);
1638 	ZEND_HASH_FOREACH_STR_KEY(&EG(included_files), entry) {
1639 		if (entry) {
1640 			add_next_index_str(return_value, zend_string_copy(entry));
1641 		}
1642 	} ZEND_HASH_FOREACH_END();
1643 }
1644 /* }}} */
1645 
1646 /* {{{ proto void trigger_error(string message [, int error_type])
1647    Generates a user-level error/warning/notice message */
ZEND_FUNCTION(trigger_error)1648 ZEND_FUNCTION(trigger_error)
1649 {
1650 	zend_long error_type = E_USER_NOTICE;
1651 	char *message;
1652 	size_t message_len;
1653 
1654 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &message, &message_len, &error_type) == FAILURE) {
1655 		return;
1656 	}
1657 
1658 	switch (error_type) {
1659 		case E_USER_ERROR:
1660 		case E_USER_WARNING:
1661 		case E_USER_NOTICE:
1662 		case E_USER_DEPRECATED:
1663 			break;
1664 		default:
1665 			zend_error(E_WARNING, "Invalid error type specified");
1666 			RETURN_FALSE;
1667 			break;
1668 	}
1669 
1670 	zend_error((int)error_type, "%s", message);
1671 	RETURN_TRUE;
1672 }
1673 /* }}} */
1674 
1675 /* {{{ proto string set_error_handler(callable error_handler [, int error_types])
1676    Sets a user-defined error handler function.  Returns the previously defined error handler, or false on error */
ZEND_FUNCTION(set_error_handler)1677 ZEND_FUNCTION(set_error_handler)
1678 {
1679 	zval *error_handler;
1680 	zend_string *error_handler_name = NULL;
1681 	zend_long error_type = E_ALL;
1682 
1683 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|l", &error_handler, &error_type) == FAILURE) {
1684 		return;
1685 	}
1686 
1687 	if (Z_TYPE_P(error_handler) != IS_NULL) { /* NULL == unset */
1688 		if (!zend_is_callable(error_handler, 0, &error_handler_name)) {
1689 			zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
1690 					   get_active_function_name(), error_handler_name?ZSTR_VAL(error_handler_name):"unknown");
1691 			zend_string_release(error_handler_name);
1692 			return;
1693 		}
1694 		zend_string_release(error_handler_name);
1695 	}
1696 
1697 	if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
1698 		ZVAL_COPY(return_value, &EG(user_error_handler));
1699 
1700 		zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting));
1701 		zend_stack_push(&EG(user_error_handlers), &EG(user_error_handler));
1702 	}
1703 
1704 	if (Z_TYPE_P(error_handler) == IS_NULL) { /* unset user-defined handler */
1705 		ZVAL_UNDEF(&EG(user_error_handler));
1706 		return;
1707 	}
1708 
1709 	ZVAL_COPY(&EG(user_error_handler), error_handler);
1710 	EG(user_error_handler_error_reporting) = (int)error_type;
1711 }
1712 /* }}} */
1713 
1714 /* {{{ proto void restore_error_handler(void)
1715    Restores the previously defined error handler function */
ZEND_FUNCTION(restore_error_handler)1716 ZEND_FUNCTION(restore_error_handler)
1717 {
1718 	if (zend_parse_parameters_none() == FAILURE) {
1719 		return;
1720 	}
1721 
1722 	if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
1723 		zval zeh;
1724 
1725 		ZVAL_COPY_VALUE(&zeh, &EG(user_error_handler));
1726 		ZVAL_UNDEF(&EG(user_error_handler));
1727 		zval_ptr_dtor(&zeh);
1728 	}
1729 
1730 	if (zend_stack_is_empty(&EG(user_error_handlers))) {
1731 		ZVAL_UNDEF(&EG(user_error_handler));
1732 	} else {
1733 		zval *tmp;
1734 		EG(user_error_handler_error_reporting) = zend_stack_int_top(&EG(user_error_handlers_error_reporting));
1735 		zend_stack_del_top(&EG(user_error_handlers_error_reporting));
1736 		tmp = zend_stack_top(&EG(user_error_handlers));
1737 		ZVAL_COPY_VALUE(&EG(user_error_handler), tmp);
1738 		zend_stack_del_top(&EG(user_error_handlers));
1739 	}
1740 	RETURN_TRUE;
1741 }
1742 /* }}} */
1743 
1744 /* {{{ proto mixed set_exception_handler(callable exception_handler)
1745    Sets a user-defined exception handler function. Returns the previously defined exception handler, or false on error */
ZEND_FUNCTION(set_exception_handler)1746 ZEND_FUNCTION(set_exception_handler)
1747 {
1748 	zval *exception_handler;
1749 	zend_string *exception_handler_name = NULL;
1750 
1751 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &exception_handler) == FAILURE) {
1752 		return;
1753 	}
1754 
1755 	if (Z_TYPE_P(exception_handler) != IS_NULL) { /* NULL == unset */
1756 		if (!zend_is_callable(exception_handler, 0, &exception_handler_name)) {
1757 			zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
1758 					   get_active_function_name(), exception_handler_name?ZSTR_VAL(exception_handler_name):"unknown");
1759 			zend_string_release(exception_handler_name);
1760 			return;
1761 		}
1762 		zend_string_release(exception_handler_name);
1763 	}
1764 
1765 	if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
1766 		ZVAL_COPY(return_value, &EG(user_exception_handler));
1767 
1768 		zend_stack_push(&EG(user_exception_handlers), &EG(user_exception_handler));
1769 	}
1770 
1771 	if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */
1772 		ZVAL_UNDEF(&EG(user_exception_handler));
1773 		return;
1774 	}
1775 
1776 	ZVAL_COPY(&EG(user_exception_handler), exception_handler);
1777 }
1778 /* }}} */
1779 
1780 /* {{{ proto void restore_exception_handler(void)
1781    Restores the previously defined exception handler function */
ZEND_FUNCTION(restore_exception_handler)1782 ZEND_FUNCTION(restore_exception_handler)
1783 {
1784 	if (zend_parse_parameters_none() == FAILURE) {
1785 		return;
1786 	}
1787 
1788 	if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
1789 		zval_ptr_dtor(&EG(user_exception_handler));
1790 	}
1791 	if (zend_stack_is_empty(&EG(user_exception_handlers))) {
1792 		ZVAL_UNDEF(&EG(user_exception_handler));
1793 	} else {
1794 		zval *tmp = zend_stack_top(&EG(user_exception_handlers));
1795 		ZVAL_COPY_VALUE(&EG(user_exception_handler), tmp);
1796 		zend_stack_del_top(&EG(user_exception_handlers));
1797 	}
1798 	RETURN_TRUE;
1799 }
1800 /* }}} */
1801 
copy_class_or_interface_name(zval * el,int num_args,va_list args,zend_hash_key * hash_key)1802 static int copy_class_or_interface_name(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
1803 {
1804 	zend_class_entry *ce = (zend_class_entry *)Z_PTR_P(el);
1805 	zval *array = va_arg(args, zval *);
1806 	uint32_t mask = va_arg(args, uint32_t);
1807 	uint32_t comply = va_arg(args, uint32_t);
1808 	uint32_t comply_mask = (comply)? mask:0;
1809 
1810 	if ((hash_key->key && ZSTR_VAL(hash_key->key)[0] != 0)
1811 		&& (comply_mask == (ce->ce_flags & mask))) {
1812 		if (ce->refcount > 1 &&
1813 		    !same_name(hash_key->key, ce->name)) {
1814 			add_next_index_str(array, zend_string_copy(hash_key->key));
1815 		} else {
1816 			add_next_index_str(array, zend_string_copy(ce->name));
1817 		}
1818 	}
1819 	return ZEND_HASH_APPLY_KEEP;
1820 }
1821 /* }}} */
1822 
1823 /* {{{ proto array get_declared_traits()
1824    Returns an array of all declared traits. */
ZEND_FUNCTION(get_declared_traits)1825 ZEND_FUNCTION(get_declared_traits)
1826 {
1827 	uint32_t mask = ZEND_ACC_TRAIT;
1828 	uint32_t comply = 1;
1829 
1830 	if (zend_parse_parameters_none() == FAILURE) {
1831 		return;
1832 	}
1833 
1834 	array_init(return_value);
1835 	zend_hash_apply_with_arguments(EG(class_table), copy_class_or_interface_name, 3, return_value, mask, comply);
1836 }
1837 /* }}} */
1838 
1839 /* {{{ proto array get_declared_classes()
1840    Returns an array of all declared classes. */
ZEND_FUNCTION(get_declared_classes)1841 ZEND_FUNCTION(get_declared_classes)
1842 {
1843 	uint32_t mask = ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT;
1844 	uint32_t comply = 0;
1845 
1846 	if (zend_parse_parameters_none() == FAILURE) {
1847 		return;
1848 	}
1849 
1850 	array_init(return_value);
1851 	zend_hash_apply_with_arguments(EG(class_table), copy_class_or_interface_name, 3, return_value, mask, comply);
1852 }
1853 /* }}} */
1854 
1855 /* {{{ proto array get_declared_interfaces()
1856    Returns an array of all declared interfaces. */
ZEND_FUNCTION(get_declared_interfaces)1857 ZEND_FUNCTION(get_declared_interfaces)
1858 {
1859 	uint32_t mask = ZEND_ACC_INTERFACE;
1860 	uint32_t comply = 1;
1861 
1862 	if (zend_parse_parameters_none() == FAILURE) {
1863 		return;
1864 	}
1865 
1866 	array_init(return_value);
1867 	zend_hash_apply_with_arguments(EG(class_table), copy_class_or_interface_name, 3, return_value, mask, comply);
1868 }
1869 /* }}} */
1870 
copy_function_name(zval * zv,int num_args,va_list args,zend_hash_key * hash_key)1871 static int copy_function_name(zval *zv, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
1872 {
1873 	zend_function *func = Z_PTR_P(zv);
1874 	zval *internal_ar = va_arg(args, zval *),
1875 	     *user_ar     = va_arg(args, zval *);
1876 	zend_bool *exclude_disabled = va_arg(args, zend_bool *);
1877 
1878 	if (hash_key->key == NULL || ZSTR_VAL(hash_key->key)[0] == 0) {
1879 		return 0;
1880 	}
1881 
1882 	if (func->type == ZEND_INTERNAL_FUNCTION) {
1883 		char *disable_functions = INI_STR("disable_functions");
1884 
1885 		if ((*exclude_disabled == 1) && (disable_functions != NULL)) {
1886 			if (strstr(disable_functions, func->common.function_name->val) == NULL) {
1887 				add_next_index_str(internal_ar, zend_string_copy(hash_key->key));
1888 			}
1889 		} else {
1890 			add_next_index_str(internal_ar, zend_string_copy(hash_key->key));
1891 		}
1892 	} else if (func->type == ZEND_USER_FUNCTION) {
1893 		add_next_index_str(user_ar, zend_string_copy(hash_key->key));
1894 	}
1895 
1896 	return 0;
1897 }
1898 /* }}} */
1899 
1900 /* {{{ proto array get_defined_functions(void)
1901    Returns an array of all defined functions */
ZEND_FUNCTION(get_defined_functions)1902 ZEND_FUNCTION(get_defined_functions)
1903 {
1904 	zval internal, user;
1905 	zend_bool exclude_disabled = 0;
1906 
1907 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &exclude_disabled) == FAILURE) {
1908 		return;
1909 	}
1910 
1911 	array_init(&internal);
1912 	array_init(&user);
1913 	array_init(return_value);
1914 
1915 	zend_hash_apply_with_arguments(EG(function_table), copy_function_name, 3, &internal, &user, &exclude_disabled);
1916 
1917 	zend_hash_str_add_new(Z_ARRVAL_P(return_value), "internal", sizeof("internal")-1, &internal);
1918 	zend_hash_str_add_new(Z_ARRVAL_P(return_value), "user", sizeof("user")-1, &user);
1919 }
1920 /* }}} */
1921 
1922 /* {{{ proto array get_defined_vars(void)
1923    Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */
ZEND_FUNCTION(get_defined_vars)1924 ZEND_FUNCTION(get_defined_vars)
1925 {
1926 	zend_array *symbol_table = zend_rebuild_symbol_table();
1927 
1928 	if (UNEXPECTED(symbol_table == NULL)) {
1929 		return;
1930 	}
1931 
1932 	RETURN_ARR(zend_array_dup(symbol_table));
1933 }
1934 /* }}} */
1935 
1936 #define LAMBDA_TEMP_FUNCNAME	"__lambda_func"
1937 /* {{{ proto string create_function(string args, string code)
1938    Creates an anonymous function, and returns its name (funny, eh?) */
ZEND_FUNCTION(create_function)1939 ZEND_FUNCTION(create_function)
1940 {
1941     zend_string *function_name;
1942 	char *eval_code, *function_args, *function_code;
1943 	size_t eval_code_length, function_args_len, function_code_len;
1944 	int retval;
1945 	char *eval_name;
1946 
1947 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &function_args, &function_args_len, &function_code, &function_code_len) == FAILURE) {
1948 		return;
1949 	}
1950 
1951 	eval_code = (char *) emalloc(sizeof("function " LAMBDA_TEMP_FUNCNAME)
1952 			+function_args_len
1953 			+2	/* for the args parentheses */
1954 			+2	/* for the curly braces */
1955 			+function_code_len);
1956 
1957 	eval_code_length = sizeof("function " LAMBDA_TEMP_FUNCNAME "(") - 1;
1958 	memcpy(eval_code, "function " LAMBDA_TEMP_FUNCNAME "(", eval_code_length);
1959 
1960 	memcpy(eval_code + eval_code_length, function_args, function_args_len);
1961 	eval_code_length += function_args_len;
1962 
1963 	eval_code[eval_code_length++] = ')';
1964 	eval_code[eval_code_length++] = '{';
1965 
1966 	memcpy(eval_code + eval_code_length, function_code, function_code_len);
1967 	eval_code_length += function_code_len;
1968 
1969 	eval_code[eval_code_length++] = '}';
1970 	eval_code[eval_code_length] = '\0';
1971 
1972 	eval_name = zend_make_compiled_string_description("runtime-created function");
1973 	retval = zend_eval_stringl(eval_code, eval_code_length, NULL, eval_name);
1974 	efree(eval_code);
1975 	efree(eval_name);
1976 
1977 	if (retval==SUCCESS) {
1978 		zend_op_array *func;
1979 		HashTable *static_variables;
1980 
1981 		func = zend_hash_str_find_ptr(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)-1);
1982 		if (!func) {
1983 			zend_error_noreturn(E_CORE_ERROR, "Unexpected inconsistency in create_function()");
1984 			RETURN_FALSE;
1985 		}
1986 		if (func->refcount) {
1987 			(*func->refcount)++;
1988 		}
1989 		static_variables = func->static_variables;
1990 		func->static_variables = NULL;
1991 		zend_hash_str_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)-1);
1992 		func->static_variables = static_variables;
1993 
1994 		function_name = zend_string_alloc(sizeof("0lambda_")+MAX_LENGTH_OF_LONG, 0);
1995 		ZSTR_VAL(function_name)[0] = '\0';
1996 
1997 		do {
1998 			ZSTR_LEN(function_name) = snprintf(ZSTR_VAL(function_name) + 1, sizeof("lambda_")+MAX_LENGTH_OF_LONG, "lambda_%d", ++EG(lambda_count)) + 1;
1999 		} while (zend_hash_add_ptr(EG(function_table), function_name, func) == NULL);
2000 		RETURN_NEW_STR(function_name);
2001 	} else {
2002 		zend_hash_str_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)-1);
2003 		RETURN_FALSE;
2004 	}
2005 }
2006 /* }}} */
2007 
2008 #if ZEND_DEBUG
ZEND_FUNCTION(zend_test_func)2009 ZEND_FUNCTION(zend_test_func)
2010 {
2011 	zval *arg1, *arg2;
2012 
2013 	zend_get_parameters(ZEND_NUM_ARGS(), 2, &arg1, &arg2);
2014 }
2015 
ZEND_FUNCTION(zend_test_func2)2016 ZEND_FUNCTION(zend_test_func2)
2017 {
2018 	zval *arg1, *arg2;
2019 
2020 	zend_get_parameters(ZEND_NUM_ARGS(), 2, &arg1, &arg2);
2021 }
2022 
2023 
2024 #ifdef ZTS
ZEND_FUNCTION(zend_thread_id)2025 ZEND_FUNCTION(zend_thread_id)
2026 {
2027 	RETURN_LONG((zend_long)tsrm_thread_id());
2028 }
2029 #endif
2030 #endif
2031 
2032 /* {{{ proto string get_resource_type(resource res)
2033    Get the resource type name for a given resource */
ZEND_FUNCTION(get_resource_type)2034 ZEND_FUNCTION(get_resource_type)
2035 {
2036 	const char *resource_type;
2037 	zval *z_resource_type;
2038 
2039 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_resource_type) == FAILURE) {
2040 		return;
2041 	}
2042 
2043 	resource_type = zend_rsrc_list_get_rsrc_type(Z_RES_P(z_resource_type));
2044 	if (resource_type) {
2045 		RETURN_STRING(resource_type);
2046 	} else {
2047 		RETURN_STRING("Unknown");
2048 	}
2049 }
2050 /* }}} */
2051 
2052 /* {{{ proto array get_resources([string resouce_type])
2053    Get an array with all active resources */
ZEND_FUNCTION(get_resources)2054 ZEND_FUNCTION(get_resources)
2055 {
2056 	zend_string *type = NULL;
2057 	zend_string *key;
2058 	zend_ulong index;
2059 	zval *val;
2060 
2061 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S", &type) == FAILURE) {
2062 		return;
2063 	}
2064 
2065 	if (!type) {
2066 		array_init(return_value);
2067 		ZEND_HASH_FOREACH_KEY_VAL(&EG(regular_list), index, key, val) {
2068 			if (!key) {
2069 				Z_ADDREF_P(val);
2070 				zend_hash_index_add_new(Z_ARRVAL_P(return_value), index, val);
2071 			}
2072 		} ZEND_HASH_FOREACH_END();
2073 	} else if (zend_string_equals_literal(type, "Unknown")) {
2074 		array_init(return_value);
2075 		ZEND_HASH_FOREACH_KEY_VAL(&EG(regular_list), index, key, val) {
2076 			if (!key && Z_RES_TYPE_P(val) <= 0) {
2077 				Z_ADDREF_P(val);
2078 				zend_hash_index_add_new(Z_ARRVAL_P(return_value), index, val);
2079 			}
2080 		} ZEND_HASH_FOREACH_END();
2081 	} else {
2082 		int id = zend_fetch_list_dtor_id(ZSTR_VAL(type));
2083 
2084 		if (id <= 0) {
2085 			zend_error(E_WARNING, "get_resources():  Unknown resource type '%s'", ZSTR_VAL(type));
2086 			RETURN_FALSE;
2087 		}
2088 
2089 		array_init(return_value);
2090 		ZEND_HASH_FOREACH_KEY_VAL(&EG(regular_list), index, key, val) {
2091 			if (!key && Z_RES_TYPE_P(val) == id) {
2092 				Z_ADDREF_P(val);
2093 				zend_hash_index_add_new(Z_ARRVAL_P(return_value), index, val);
2094 			}
2095 		} ZEND_HASH_FOREACH_END();
2096 	}
2097 }
2098 /* }}} */
2099 
add_extension_info(zval * item,void * arg)2100 static int add_extension_info(zval *item, void *arg) /* {{{ */
2101 {
2102 	zval *name_array = (zval *)arg;
2103 	zend_module_entry *module = (zend_module_entry*)Z_PTR_P(item);
2104 	add_next_index_string(name_array, module->name);
2105 	return 0;
2106 }
2107 /* }}} */
2108 
add_zendext_info(zend_extension * ext,void * arg)2109 static int add_zendext_info(zend_extension *ext, void *arg) /* {{{ */
2110 {
2111 	zval *name_array = (zval *)arg;
2112 	add_next_index_string(name_array, ext->name);
2113 	return 0;
2114 }
2115 /* }}} */
2116 
add_constant_info(zval * item,void * arg)2117 static int add_constant_info(zval *item, void *arg) /* {{{ */
2118 {
2119 	zval *name_array = (zval *)arg;
2120 	zend_constant *constant = (zend_constant*)Z_PTR_P(item);
2121 	zval const_val;
2122 
2123 	if (!constant->name) {
2124 		/* skip special constants */
2125 		return 0;
2126 	}
2127 
2128 	ZVAL_DUP(&const_val, &constant->value);
2129 	zend_hash_add_new(Z_ARRVAL_P(name_array), constant->name, &const_val);
2130 	return 0;
2131 }
2132 /* }}} */
2133 
2134 /* {{{ proto array get_loaded_extensions([bool zend_extensions])
2135    Return an array containing names of loaded extensions */
ZEND_FUNCTION(get_loaded_extensions)2136 ZEND_FUNCTION(get_loaded_extensions)
2137 {
2138 	zend_bool zendext = 0;
2139 
2140 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &zendext) == FAILURE) {
2141 		return;
2142 	}
2143 
2144 	array_init(return_value);
2145 
2146 	if (zendext) {
2147 		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t)add_zendext_info, return_value);
2148 	} else {
2149 		zend_hash_apply_with_argument(&module_registry, add_extension_info, return_value);
2150 	}
2151 }
2152 /* }}} */
2153 
2154 /* {{{ proto array get_defined_constants([bool categorize])
2155    Return an array containing the names and values of all defined constants */
ZEND_FUNCTION(get_defined_constants)2156 ZEND_FUNCTION(get_defined_constants)
2157 {
2158 	zend_bool categorize = 0;
2159 
2160 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &categorize) == FAILURE) {
2161 		return;
2162 	}
2163 
2164 	array_init(return_value);
2165 
2166 	if (categorize) {
2167 		zend_constant *val;
2168 		int module_number;
2169 		zval *modules, const_val;
2170 		char **module_names;
2171 		zend_module_entry *module;
2172 		int i = 1;
2173 
2174 		modules = ecalloc(zend_hash_num_elements(&module_registry) + 2, sizeof(zval));
2175 		module_names = emalloc((zend_hash_num_elements(&module_registry) + 2) * sizeof(char *));
2176 
2177 		module_names[0] = "internal";
2178 		ZEND_HASH_FOREACH_PTR(&module_registry, module) {
2179 			module_names[module->module_number] = (char *)module->name;
2180 			i++;
2181 		} ZEND_HASH_FOREACH_END();
2182 		module_names[i] = "user";
2183 
2184 		ZEND_HASH_FOREACH_PTR(EG(zend_constants), val) {
2185 			if (!val->name) {
2186 				/* skip special constants */
2187 				continue;
2188 			}
2189 
2190 			if (val->module_number == PHP_USER_CONSTANT) {
2191 				module_number = i;
2192 			} else if (val->module_number > i || val->module_number < 0) {
2193 				/* should not happen */
2194 				continue;
2195 			} else {
2196 				module_number = val->module_number;
2197 			}
2198 
2199 			if (Z_TYPE(modules[module_number]) == IS_UNDEF) {
2200 				array_init(&modules[module_number]);
2201 				add_assoc_zval(return_value, module_names[module_number], &modules[module_number]);
2202 			}
2203 
2204 			ZVAL_DUP(&const_val, &val->value);
2205 			zend_hash_add_new(Z_ARRVAL(modules[module_number]), val->name, &const_val);
2206 		} ZEND_HASH_FOREACH_END();
2207 
2208 		efree(module_names);
2209 		efree(modules);
2210 	} else {
2211 		zend_hash_apply_with_argument(EG(zend_constants), add_constant_info, return_value);
2212 	}
2213 }
2214 /* }}} */
2215 
debug_backtrace_get_args(zend_execute_data * call,zval * arg_array)2216 static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /* {{{ */
2217 {
2218 	uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
2219 
2220 	array_init_size(arg_array, num_args);
2221 	if (num_args) {
2222 		uint32_t i = 0;
2223 		zval *p = ZEND_CALL_ARG(call, 1);
2224 
2225 		zend_hash_real_init(Z_ARRVAL_P(arg_array), 1);
2226 		ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(arg_array)) {
2227 			if (call->func->type == ZEND_USER_FUNCTION) {
2228 				uint32_t first_extra_arg = MIN(num_args, call->func->op_array.num_args);
2229 
2230 				if (UNEXPECTED(call->symbol_table)) {
2231 					/* In case of attached symbol_table, values on stack may be invalid
2232 					 * and we have to access them through symbol_table
2233 					 * See: https://bugs.php.net/bug.php?id=73156
2234 					 */
2235 					zend_string *arg_name;
2236 					zval *arg;
2237 
2238 					while (i < first_extra_arg) {
2239 						arg_name = call->func->op_array.vars[i];
2240 						arg = zend_hash_find_ind(call->symbol_table, arg_name);
2241 						if (arg) {
2242 							if (Z_OPT_REFCOUNTED_P(arg)) {
2243 								Z_ADDREF_P(arg);
2244 							}
2245 							ZEND_HASH_FILL_ADD(arg);
2246 						} else {
2247 							ZEND_HASH_FILL_ADD(&EG(uninitialized_zval));
2248 						}
2249 						i++;
2250 					}
2251 				} else {
2252 					while (i < first_extra_arg) {
2253 						if (EXPECTED(Z_TYPE_INFO_P(p) != IS_UNDEF)) {
2254 							if (Z_OPT_REFCOUNTED_P(p)) {
2255 								Z_ADDREF_P(p);
2256 							}
2257 							ZEND_HASH_FILL_ADD(p);
2258 						} else {
2259 							ZEND_HASH_FILL_ADD(&EG(uninitialized_zval));
2260 						}
2261 						p++;
2262 						i++;
2263 					}
2264 				}
2265 				p = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var + call->func->op_array.T);
2266 			}
2267 
2268 			while (i < num_args) {
2269 				if (EXPECTED(Z_TYPE_INFO_P(p) != IS_UNDEF)) {
2270 					if (Z_OPT_REFCOUNTED_P(p)) {
2271 						Z_ADDREF_P(p);
2272 					}
2273 					ZEND_HASH_FILL_ADD(p);
2274 				} else {
2275 					ZEND_HASH_FILL_ADD(&EG(uninitialized_zval));
2276 				}
2277 				p++;
2278 				i++;
2279 			}
2280 		} ZEND_HASH_FILL_END();
2281 		Z_ARRVAL_P(arg_array)->nNumOfElements = num_args;
2282 	}
2283 }
2284 /* }}} */
2285 
debug_print_backtrace_args(zval * arg_array)2286 void debug_print_backtrace_args(zval *arg_array) /* {{{ */
2287 {
2288 	zval *tmp;
2289 	int i = 0;
2290 
2291 	ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arg_array), tmp) {
2292 		if (i++) {
2293 			ZEND_PUTS(", ");
2294 		}
2295 		zend_print_flat_zval_r(tmp);
2296 	} ZEND_HASH_FOREACH_END();
2297 }
2298 /* }}} */
2299 
2300 /* {{{ proto void debug_print_backtrace([int options[, int limit]]) */
ZEND_FUNCTION(debug_print_backtrace)2301 ZEND_FUNCTION(debug_print_backtrace)
2302 {
2303 	zend_execute_data *call, *ptr, *skip;
2304 	zend_object *object;
2305 	int lineno, frameno = 0;
2306 	zend_function *func;
2307 	const char *function_name;
2308 	const char *filename;
2309 	zend_string *class_name = NULL;
2310 	char *call_type;
2311 	const char *include_filename = NULL;
2312 	zval arg_array;
2313 	int indent = 0;
2314 	zend_long options = 0;
2315 	zend_long limit = 0;
2316 
2317 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ll", &options, &limit) == FAILURE) {
2318 		return;
2319 	}
2320 
2321 	ZVAL_UNDEF(&arg_array);
2322 	ptr = EX(prev_execute_data);
2323 
2324 	/* skip debug_backtrace() */
2325 	call = ptr;
2326 	ptr = ptr->prev_execute_data;
2327 
2328 	while (ptr && (limit == 0 || frameno < limit)) {
2329 		frameno++;
2330 		class_name = NULL;
2331 		call_type = NULL;
2332 		ZVAL_UNDEF(&arg_array);
2333 
2334 		ptr = zend_generator_check_placeholder_frame(ptr);
2335 
2336 		skip = ptr;
2337 		/* skip internal handler */
2338 		if ((!skip->func || !ZEND_USER_CODE(skip->func->common.type)) &&
2339 		    skip->prev_execute_data &&
2340 		    skip->prev_execute_data->func &&
2341 		    ZEND_USER_CODE(skip->prev_execute_data->func->common.type) &&
2342 		    skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
2343 		    skip->prev_execute_data->opline->opcode != ZEND_DO_ICALL &&
2344 		    skip->prev_execute_data->opline->opcode != ZEND_DO_UCALL &&
2345 		    skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
2346 		    skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
2347 			skip = skip->prev_execute_data;
2348 		}
2349 
2350 		if (skip->func && ZEND_USER_CODE(skip->func->common.type)) {
2351 			filename = ZSTR_VAL(skip->func->op_array.filename);
2352 			if (skip->opline->opcode == ZEND_HANDLE_EXCEPTION) {
2353 				if (EG(opline_before_exception)) {
2354 					lineno = EG(opline_before_exception)->lineno;
2355 				} else {
2356 					lineno = skip->func->op_array.line_end;
2357 				}
2358 			} else {
2359 				lineno = skip->opline->lineno;
2360 			}
2361 		} else {
2362 			filename = NULL;
2363 			lineno = 0;
2364 		}
2365 
2366 		/* $this may be passed into regular internal functions */
2367 		object = Z_OBJ(call->This);
2368 
2369 		if (call->func) {
2370 			zend_string *zend_function_name;
2371 
2372 			func = call->func;
2373             if (func->common.scope && func->common.scope->trait_aliases) {
2374                 zend_function_name = zend_resolve_method_name(object ? object->ce : func->common.scope, func);
2375             } else {
2376                 zend_function_name = func->common.function_name;
2377             }
2378             if (zend_function_name != NULL) {
2379                 function_name = ZSTR_VAL(zend_function_name);
2380             } else {
2381                 function_name = NULL;
2382             }
2383 		} else {
2384 			func = NULL;
2385 			function_name = NULL;
2386 		}
2387 
2388 		if (function_name) {
2389 			if (object) {
2390 				if (func->common.scope) {
2391 					class_name = func->common.scope->name;
2392 				} else if (object->handlers->get_class_name == std_object_handlers.get_class_name) {
2393 					class_name = object->ce->name;
2394 				} else {
2395 					class_name = object->handlers->get_class_name(object);
2396 				}
2397 
2398 				call_type = "->";
2399 			} else if (func->common.scope) {
2400 				class_name = func->common.scope->name;
2401 				call_type = "::";
2402 			} else {
2403 				class_name = NULL;
2404 				call_type = NULL;
2405 			}
2406 			if (func->type != ZEND_EVAL_CODE) {
2407 				if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0) {
2408 					debug_backtrace_get_args(call, &arg_array);
2409 				}
2410 			}
2411 		} else {
2412 			/* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
2413 			zend_bool build_filename_arg = 1;
2414 
2415 			if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type) || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
2416 				/* can happen when calling eval from a custom sapi */
2417 				function_name = "unknown";
2418 				build_filename_arg = 0;
2419 			} else
2420 			switch (ptr->opline->extended_value) {
2421 				case ZEND_EVAL:
2422 					function_name = "eval";
2423 					build_filename_arg = 0;
2424 					break;
2425 				case ZEND_INCLUDE:
2426 					function_name = "include";
2427 					break;
2428 				case ZEND_REQUIRE:
2429 					function_name = "require";
2430 					break;
2431 				case ZEND_INCLUDE_ONCE:
2432 					function_name = "include_once";
2433 					break;
2434 				case ZEND_REQUIRE_ONCE:
2435 					function_name = "require_once";
2436 					break;
2437 				default:
2438 					/* this can actually happen if you use debug_backtrace() in your error_handler and
2439 					 * you're in the top-scope */
2440 					function_name = "unknown";
2441 					build_filename_arg = 0;
2442 					break;
2443 			}
2444 
2445 			if (build_filename_arg && include_filename) {
2446 				array_init(&arg_array);
2447 				add_next_index_string(&arg_array, (char*)include_filename);
2448 			}
2449 			call_type = NULL;
2450 		}
2451 		zend_printf("#%-2d ", indent);
2452 		if (class_name) {
2453 			ZEND_PUTS(ZSTR_VAL(class_name));
2454 			ZEND_PUTS(call_type);
2455 			if (object
2456 			  && !func->common.scope
2457 			  && object->handlers->get_class_name != std_object_handlers.get_class_name) {
2458 				zend_string_release(class_name);
2459 			}
2460 		}
2461 		zend_printf("%s(", function_name);
2462 		if (Z_TYPE(arg_array) != IS_UNDEF) {
2463 			debug_print_backtrace_args(&arg_array);
2464 			zval_ptr_dtor(&arg_array);
2465 		}
2466 		if (filename) {
2467 			zend_printf(") called at [%s:%d]\n", filename, lineno);
2468 		} else {
2469 			zend_execute_data *prev_call = skip;
2470 			zend_execute_data *prev = skip->prev_execute_data;
2471 
2472 			while (prev) {
2473 				if (prev_call &&
2474 				    prev_call->func &&
2475 					!ZEND_USER_CODE(prev_call->func->common.type)) {
2476 					prev = NULL;
2477 					break;
2478 				}
2479 				if (prev->func && ZEND_USER_CODE(prev->func->common.type)) {
2480 					zend_printf(") called at [%s:%d]\n", ZSTR_VAL(prev->func->op_array.filename), prev->opline->lineno);
2481 					break;
2482 				}
2483 				prev_call = prev;
2484 				prev = prev->prev_execute_data;
2485 			}
2486 			if (!prev) {
2487 				ZEND_PUTS(")\n");
2488 			}
2489 		}
2490 		include_filename = filename;
2491 		call = skip;
2492 		ptr = skip->prev_execute_data;
2493 		++indent;
2494 	}
2495 }
2496 
2497 /* }}} */
2498 
zend_fetch_debug_backtrace(zval * return_value,int skip_last,int options,int limit)2499 ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options, int limit) /* {{{ */
2500 {
2501 	zend_execute_data *ptr, *skip, *call = NULL;
2502 	zend_object *object;
2503 	int lineno, frameno = 0;
2504 	zend_function *func;
2505 	zend_string *function_name;
2506 	zend_string *filename;
2507 	zend_string *include_filename = NULL;
2508 	zval stack_frame;
2509 
2510 	array_init(return_value);
2511 
2512 	if (!(ptr = EG(current_execute_data))) {
2513 		return;
2514 	}
2515 
2516 	if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type)) {
2517 		call = ptr;
2518 		ptr = ptr->prev_execute_data;
2519 	}
2520 
2521 	if (ptr) {
2522 		if (skip_last) {
2523 			/* skip debug_backtrace() */
2524 			call = ptr;
2525 			ptr = ptr->prev_execute_data;
2526 		} else {
2527 			/* skip "new Exception()" */
2528 			if (ptr->func && ZEND_USER_CODE(ptr->func->common.type) && (ptr->opline->opcode == ZEND_NEW)) {
2529 				call = ptr;
2530 				ptr = ptr->prev_execute_data;
2531 			}
2532 		}
2533 		if (!call) {
2534 			call = ptr;
2535 			ptr = ptr->prev_execute_data;
2536 		}
2537 	}
2538 
2539 	while (ptr && (limit == 0 || frameno < limit)) {
2540 		frameno++;
2541 		array_init(&stack_frame);
2542 
2543 		ptr = zend_generator_check_placeholder_frame(ptr);
2544 
2545 		skip = ptr;
2546 		/* skip internal handler */
2547 		if ((!skip->func || !ZEND_USER_CODE(skip->func->common.type)) &&
2548 		    skip->prev_execute_data &&
2549 		    skip->prev_execute_data->func &&
2550 		    ZEND_USER_CODE(skip->prev_execute_data->func->common.type) &&
2551 		    skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
2552 		    skip->prev_execute_data->opline->opcode != ZEND_DO_ICALL &&
2553 		    skip->prev_execute_data->opline->opcode != ZEND_DO_UCALL &&
2554 		    skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
2555 		    skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
2556 			skip = skip->prev_execute_data;
2557 		}
2558 
2559 		if (skip->func && ZEND_USER_CODE(skip->func->common.type)) {
2560 			filename = skip->func->op_array.filename;
2561 			if (skip->opline->opcode == ZEND_HANDLE_EXCEPTION) {
2562 				if (EG(opline_before_exception)) {
2563 					lineno = EG(opline_before_exception)->lineno;
2564 				} else {
2565 					lineno = skip->func->op_array.line_end;
2566 				}
2567 			} else {
2568 				lineno = skip->opline->lineno;
2569 			}
2570 			add_assoc_str_ex(&stack_frame, "file", sizeof("file")-1, zend_string_copy(filename));
2571 			add_assoc_long_ex(&stack_frame, "line", sizeof("line")-1, lineno);
2572 
2573 			/* try to fetch args only if an FCALL was just made - elsewise we're in the middle of a function
2574 			 * and debug_baktrace() might have been called by the error_handler. in this case we don't
2575 			 * want to pop anything of the argument-stack */
2576 		} else {
2577 			zend_execute_data *prev_call = skip;
2578 			zend_execute_data *prev = skip->prev_execute_data;
2579 
2580 			while (prev) {
2581 				if (prev_call &&
2582 				    prev_call->func &&
2583 					!ZEND_USER_CODE(prev_call->func->common.type) &&
2584 					!(prev_call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
2585 					break;
2586 				}
2587 				if (prev->func && ZEND_USER_CODE(prev->func->common.type)) {
2588 					add_assoc_str_ex(&stack_frame, "file", sizeof("file")-1, zend_string_copy(prev->func->op_array.filename));
2589 					add_assoc_long_ex(&stack_frame, "line", sizeof("line")-1, prev->opline->lineno);
2590 					break;
2591 				}
2592 				prev_call = prev;
2593 				prev = prev->prev_execute_data;
2594 			}
2595 			filename = NULL;
2596 		}
2597 
2598 		/* $this may be passed into regular internal functions */
2599 		object = call ? Z_OBJ(call->This) : NULL;
2600 
2601 		if (call && call->func) {
2602 			func = call->func;
2603 			function_name = (func->common.scope &&
2604 			                 func->common.scope->trait_aliases) ?
2605 				zend_resolve_method_name(
2606 					(object ? object->ce : func->common.scope), func) :
2607 				func->common.function_name;
2608 		} else {
2609 			func = NULL;
2610 			function_name = NULL;
2611 		}
2612 
2613 		if (function_name) {
2614 			add_assoc_str_ex(&stack_frame, "function", sizeof("function")-1, zend_string_copy(function_name));
2615 
2616 			if (object) {
2617 				if (func->common.scope) {
2618 					add_assoc_str_ex(&stack_frame, "class", sizeof("class")-1, zend_string_copy(func->common.scope->name));
2619 				} else if (object->handlers->get_class_name == std_object_handlers.get_class_name) {
2620 					add_assoc_str_ex(&stack_frame, "class", sizeof("class")-1, zend_string_copy(object->ce->name));
2621 				} else {
2622 					zend_string *class_name = object->handlers->get_class_name(object);
2623 					add_assoc_str_ex(&stack_frame, "class", sizeof("class")-1, class_name);
2624 				}
2625 				if ((options & DEBUG_BACKTRACE_PROVIDE_OBJECT) != 0) {
2626 					zval zv;
2627 					ZVAL_OBJ(&zv, object);
2628 					add_assoc_zval_ex(&stack_frame, "object", sizeof("object")-1, &zv);
2629 					Z_ADDREF(zv);
2630 				}
2631 
2632 				add_assoc_string_ex(&stack_frame, "type", sizeof("type")-1, "->");
2633 			} else if (func->common.scope) {
2634 				add_assoc_str_ex(&stack_frame, "class", sizeof("class")-1, zend_string_copy(func->common.scope->name));
2635 				add_assoc_string_ex(&stack_frame, "type", sizeof("type")-1, "::");
2636 			}
2637 
2638 			if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0 &&
2639 				func->type != ZEND_EVAL_CODE) {
2640 				zval args;
2641 
2642 				debug_backtrace_get_args(call, &args);
2643 				add_assoc_zval_ex(&stack_frame, "args", sizeof("args")-1, &args);
2644 			}
2645 		} else {
2646 			/* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
2647 			zend_bool build_filename_arg = 1;
2648 			const char *pseudo_function_name;
2649 
2650 			if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type) || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
2651 				/* can happen when calling eval from a custom sapi */
2652 				pseudo_function_name = "unknown";
2653 				build_filename_arg = 0;
2654 			} else
2655 			switch (ptr->opline->extended_value) {
2656 				case ZEND_EVAL:
2657 					pseudo_function_name = "eval";
2658 					build_filename_arg = 0;
2659 					break;
2660 				case ZEND_INCLUDE:
2661 					pseudo_function_name = "include";
2662 					break;
2663 				case ZEND_REQUIRE:
2664 					pseudo_function_name = "require";
2665 					break;
2666 				case ZEND_INCLUDE_ONCE:
2667 					pseudo_function_name = "include_once";
2668 					break;
2669 				case ZEND_REQUIRE_ONCE:
2670 					pseudo_function_name = "require_once";
2671 					break;
2672 				default:
2673 					/* this can actually happen if you use debug_backtrace() in your error_handler and
2674 					 * you're in the top-scope */
2675 					pseudo_function_name = "unknown";
2676 					build_filename_arg = 0;
2677 					break;
2678 			}
2679 
2680 			if (build_filename_arg && include_filename) {
2681 				zval arg_array;
2682 
2683 				array_init(&arg_array);
2684 
2685 				/* include_filename always points to the last filename of the last last called-function.
2686 				   if we have called include in the frame above - this is the file we have included.
2687 				 */
2688 
2689 				add_next_index_str(&arg_array, zend_string_copy(include_filename));
2690 				add_assoc_zval_ex(&stack_frame, "args", sizeof("args")-1, &arg_array);
2691 			}
2692 
2693 			add_assoc_string_ex(&stack_frame, "function", sizeof("function")-1, (char *) pseudo_function_name);
2694 		}
2695 
2696 		zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &stack_frame);
2697 
2698 		include_filename = filename;
2699 
2700 		call = skip;
2701 		ptr = skip->prev_execute_data;
2702 	}
2703 }
2704 /* }}} */
2705 
2706 /* {{{ proto array debug_backtrace([int options[, int limit]])
2707    Return backtrace as array */
ZEND_FUNCTION(debug_backtrace)2708 ZEND_FUNCTION(debug_backtrace)
2709 {
2710 	zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
2711 	zend_long limit = 0;
2712 
2713 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ll", &options, &limit) == FAILURE) {
2714 		return;
2715 	}
2716 
2717 	zend_fetch_debug_backtrace(return_value, 1, options, limit);
2718 }
2719 /* }}} */
2720 
2721 /* {{{ proto bool extension_loaded(string extension_name)
2722    Returns true if the named extension is loaded */
ZEND_FUNCTION(extension_loaded)2723 ZEND_FUNCTION(extension_loaded)
2724 {
2725 	zend_string *extension_name;
2726 	zend_string *lcname;
2727 
2728 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &extension_name) == FAILURE) {
2729 		return;
2730 	}
2731 
2732 	lcname = zend_string_tolower(extension_name);
2733 	if (zend_hash_exists(&module_registry, lcname)) {
2734 		RETVAL_TRUE;
2735 	} else {
2736 		RETVAL_FALSE;
2737 	}
2738 	zend_string_release(lcname);
2739 }
2740 /* }}} */
2741 
2742 /* {{{ proto array get_extension_funcs(string extension_name)
2743    Returns an array with the names of functions belonging to the named extension */
ZEND_FUNCTION(get_extension_funcs)2744 ZEND_FUNCTION(get_extension_funcs)
2745 {
2746 	zend_string *extension_name;
2747 	zend_string *lcname;
2748 	int array;
2749 	zend_module_entry *module;
2750 	zend_function *zif;
2751 
2752 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &extension_name) == FAILURE) {
2753 		return;
2754 	}
2755 	if (strncasecmp(ZSTR_VAL(extension_name), "zend", sizeof("zend"))) {
2756 		lcname = zend_string_tolower(extension_name);
2757 		module = zend_hash_find_ptr(&module_registry, lcname);
2758 		zend_string_release(lcname);
2759 	} else {
2760 		module = zend_hash_str_find_ptr(&module_registry, "core", sizeof("core") - 1);
2761 	}
2762 
2763 	if (!module) {
2764 		RETURN_FALSE;
2765 	}
2766 
2767 	if (module->functions) {
2768 		/* avoid BC break, if functions list is empty, will return an empty array */
2769 		array_init(return_value);
2770 		array = 1;
2771 	} else {
2772 		array = 0;
2773 	}
2774 
2775 	ZEND_HASH_FOREACH_PTR(CG(function_table), zif) {
2776 		if (zif->common.type == ZEND_INTERNAL_FUNCTION
2777 			&& zif->internal_function.module == module) {
2778 			if (!array) {
2779 				array_init(return_value);
2780 				array = 1;
2781 			}
2782 			add_next_index_str(return_value, zend_string_copy(zif->common.function_name));
2783 		}
2784 	} ZEND_HASH_FOREACH_END();
2785 
2786 	if (!array) {
2787 		RETURN_FALSE;
2788 	}
2789 }
2790 /* }}} */
2791 
2792 /*
2793  * Local variables:
2794  * tab-width: 4
2795  * c-basic-offset: 4
2796  * indent-tabs-mode: t
2797  * End:
2798  */
2799