xref: /PHP-8.0/Zend/zend_execute_API.c (revision 74924ada)
1 /*
2    +----------------------------------------------------------------------+
3    | Zend Engine                                                          |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 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@php.net>                                 |
16    |          Zeev Suraski <zeev@php.net>                                 |
17    |          Dmitry Stogov <dmitry@php.net>                              |
18    +----------------------------------------------------------------------+
19 */
20 
21 #include <stdio.h>
22 #include <signal.h>
23 
24 #include "zend.h"
25 #include "zend_compile.h"
26 #include "zend_execute.h"
27 #include "zend_API.h"
28 #include "zend_stack.h"
29 #include "zend_constants.h"
30 #include "zend_extensions.h"
31 #include "zend_exceptions.h"
32 #include "zend_closures.h"
33 #include "zend_generators.h"
34 #include "zend_vm.h"
35 #include "zend_float.h"
36 #include "zend_weakrefs.h"
37 #include "zend_inheritance.h"
38 #include "zend_observer.h"
39 #ifdef HAVE_SYS_TIME_H
40 #include <sys/time.h>
41 #endif
42 #ifdef HAVE_UNISTD_H
43 #include <unistd.h>
44 #endif
45 
46 ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data);
47 ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value);
48 ZEND_API zend_class_entry *(*zend_autoload)(zend_string *name, zend_string *lc_name);
49 
50 /* true globals */
51 ZEND_API const zend_fcall_info empty_fcall_info = {0};
52 ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { NULL, NULL, NULL, NULL };
53 
54 #ifdef ZEND_WIN32
55 ZEND_TLS HANDLE tq_timer = NULL;
56 #endif
57 
58 #if 0&&ZEND_DEBUG
59 static void (*original_sigsegv_handler)(int);
60 static void zend_handle_sigsegv(void) /* {{{ */
61 {
62 	fflush(stdout);
63 	fflush(stderr);
64 	if (original_sigsegv_handler == zend_handle_sigsegv) {
65 		signal(SIGSEGV, original_sigsegv_handler);
66 	} else {
67 		signal(SIGSEGV, SIG_DFL);
68 	}
69 	{
70 
71 		fprintf(stderr, "SIGSEGV caught on opcode %d on opline %d of %s() at %s:%d\n\n",
72 				active_opline->opcode,
73 				active_opline-EG(active_op_array)->opcodes,
74 				get_active_function_name(),
75 				zend_get_executed_filename(),
76 				zend_get_executed_lineno());
77 /* See http://support.microsoft.com/kb/190351 */
78 #ifdef ZEND_WIN32
79 		fflush(stderr);
80 #endif
81 	}
82 	if (original_sigsegv_handler!=zend_handle_sigsegv) {
83 		original_sigsegv_handler(dummy);
84 	}
85 }
86 /* }}} */
87 #endif
88 
zend_extension_activator(zend_extension * extension)89 static void zend_extension_activator(zend_extension *extension) /* {{{ */
90 {
91 	if (extension->activate) {
92 		extension->activate();
93 	}
94 }
95 /* }}} */
96 
zend_extension_deactivator(zend_extension * extension)97 static void zend_extension_deactivator(zend_extension *extension) /* {{{ */
98 {
99 	if (extension->deactivate) {
100 		extension->deactivate();
101 	}
102 }
103 /* }}} */
104 
clean_non_persistent_constant_full(zval * zv)105 static int clean_non_persistent_constant_full(zval *zv) /* {{{ */
106 {
107 	zend_constant *c = Z_PTR_P(zv);
108 	return (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
109 }
110 /* }}} */
111 
clean_non_persistent_function_full(zval * zv)112 static int clean_non_persistent_function_full(zval *zv) /* {{{ */
113 {
114 	zend_function *function = Z_PTR_P(zv);
115 	return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
116 }
117 /* }}} */
118 
clean_non_persistent_class_full(zval * zv)119 static int clean_non_persistent_class_full(zval *zv) /* {{{ */
120 {
121 	zend_class_entry *ce = Z_PTR_P(zv);
122 	return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
123 }
124 /* }}} */
125 
init_executor(void)126 void init_executor(void) /* {{{ */
127 {
128 	zend_init_fpu();
129 
130 	ZVAL_NULL(&EG(uninitialized_zval));
131 	ZVAL_ERROR(&EG(error_zval));
132 /* destroys stack frame, therefore makes core dumps worthless */
133 #if 0&&ZEND_DEBUG
134 	original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv);
135 #endif
136 
137 	EG(symtable_cache_ptr) = EG(symtable_cache);
138 	EG(symtable_cache_limit) = EG(symtable_cache) + SYMTABLE_CACHE_SIZE;
139 	EG(no_extensions) = 0;
140 
141 	EG(function_table) = CG(function_table);
142 	EG(class_table) = CG(class_table);
143 
144 	EG(in_autoload) = NULL;
145 	EG(error_handling) = EH_NORMAL;
146 	EG(flags) = EG_FLAGS_INITIAL;
147 
148 	zend_vm_stack_init();
149 
150 	zend_hash_init(&EG(symbol_table), 64, NULL, ZVAL_PTR_DTOR, 0);
151 
152 	zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator);
153 
154 	zend_hash_init(&EG(included_files), 8, NULL, NULL, 0);
155 
156 	EG(ticks_count) = 0;
157 
158 	ZVAL_UNDEF(&EG(user_error_handler));
159 	ZVAL_UNDEF(&EG(user_exception_handler));
160 
161 	EG(current_execute_data) = NULL;
162 
163 	zend_stack_init(&EG(user_error_handlers_error_reporting), sizeof(int));
164 	zend_stack_init(&EG(user_error_handlers), sizeof(zval));
165 	zend_stack_init(&EG(user_exception_handlers), sizeof(zval));
166 
167 	zend_objects_store_init(&EG(objects_store), 1024);
168 
169 	EG(full_tables_cleanup) = 0;
170 	EG(vm_interrupt) = 0;
171 	EG(timed_out) = 0;
172 
173 	EG(exception) = NULL;
174 	EG(prev_exception) = NULL;
175 
176 	EG(fake_scope) = NULL;
177 	EG(trampoline).common.function_name = NULL;
178 
179 	EG(ht_iterators_count) = sizeof(EG(ht_iterators_slots)) / sizeof(HashTableIterator);
180 	EG(ht_iterators_used) = 0;
181 	EG(ht_iterators) = EG(ht_iterators_slots);
182 	memset(EG(ht_iterators), 0, sizeof(EG(ht_iterators_slots)));
183 
184 	EG(persistent_constants_count) = EG(zend_constants)->nNumUsed;
185 	EG(persistent_functions_count) = EG(function_table)->nNumUsed;
186 	EG(persistent_classes_count)   = EG(class_table)->nNumUsed;
187 
188 	EG(get_gc_buffer).start = EG(get_gc_buffer).end = EG(get_gc_buffer).cur = NULL;
189 
190 	zend_weakrefs_init();
191 
192 	EG(active) = 1;
193 }
194 /* }}} */
195 
zval_call_destructor(zval * zv)196 static int zval_call_destructor(zval *zv) /* {{{ */
197 {
198 	if (Z_TYPE_P(zv) == IS_INDIRECT) {
199 		zv = Z_INDIRECT_P(zv);
200 	}
201 	if (Z_TYPE_P(zv) == IS_OBJECT && Z_REFCOUNT_P(zv) == 1) {
202 		return ZEND_HASH_APPLY_REMOVE;
203 	} else {
204 		return ZEND_HASH_APPLY_KEEP;
205 	}
206 }
207 /* }}} */
208 
zend_unclean_zval_ptr_dtor(zval * zv)209 static void zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */
210 {
211 	if (Z_TYPE_P(zv) == IS_INDIRECT) {
212 		zv = Z_INDIRECT_P(zv);
213 	}
214 	i_zval_ptr_dtor(zv);
215 }
216 /* }}} */
217 
zend_throw_or_error(int fetch_type,zend_class_entry * exception_ce,const char * format,...)218 static ZEND_COLD void zend_throw_or_error(int fetch_type, zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
219 {
220 	va_list va;
221 	char *message = NULL;
222 
223 	va_start(va, format);
224 	zend_vspprintf(&message, 0, format, va);
225 
226 	if (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) {
227 		zend_throw_error(exception_ce, "%s", message);
228 	} else {
229 		zend_error(E_ERROR, "%s", message);
230 	}
231 
232 	efree(message);
233 	va_end(va);
234 }
235 /* }}} */
236 
shutdown_destructors(void)237 void shutdown_destructors(void) /* {{{ */
238 {
239 	if (CG(unclean_shutdown)) {
240 		EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
241 	}
242 	zend_try {
243 		uint32_t symbols;
244 		do {
245 			symbols = zend_hash_num_elements(&EG(symbol_table));
246 			zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor);
247 		} while (symbols != zend_hash_num_elements(&EG(symbol_table)));
248 		zend_objects_store_call_destructors(&EG(objects_store));
249 	} zend_catch {
250 		/* if we couldn't destruct cleanly, mark all objects as destructed anyway */
251 		zend_objects_store_mark_destructed(&EG(objects_store));
252 	} zend_end_try();
253 }
254 /* }}} */
255 
shutdown_executor(void)256 void shutdown_executor(void) /* {{{ */
257 {
258 	zend_string *key;
259 	zval *zv;
260 #if ZEND_DEBUG
261 	zend_bool fast_shutdown = 0;
262 #else
263 	zend_bool fast_shutdown = is_zend_mm() && !EG(full_tables_cleanup);
264 #endif
265 
266 	zend_try {
267 		zend_llist_destroy(&CG(open_files));
268 	} zend_end_try();
269 
270 	EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN;
271 	zend_try {
272 		zend_close_rsrc_list(&EG(regular_list));
273 	} zend_end_try();
274 
275 	/* No PHP callback functions should be called after this point. */
276 	EG(active) = 0;
277 
278 	if (!fast_shutdown) {
279 		zend_hash_graceful_reverse_destroy(&EG(symbol_table));
280 
281 		/* Release static properties and static variables prior to the final GC run,
282 		 * as they may hold GC roots. */
283 		ZEND_HASH_REVERSE_FOREACH_VAL(EG(function_table), zv) {
284 			zend_op_array *op_array = Z_PTR_P(zv);
285 			if (op_array->type == ZEND_INTERNAL_FUNCTION) {
286 				break;
287 			}
288 			if (op_array->static_variables) {
289 				HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
290 				if (ht) {
291 					zend_array_release(ht);
292 					ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
293 				}
294 			}
295 		} ZEND_HASH_FOREACH_END();
296 		ZEND_HASH_REVERSE_FOREACH_VAL(EG(class_table), zv) {
297 			zend_class_entry *ce = Z_PTR_P(zv);
298 			if (ce->default_static_members_count) {
299 				zend_cleanup_internal_class_data(ce);
300 			}
301 			if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
302 				zend_op_array *op_array;
303 				ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
304 					if (op_array->type == ZEND_USER_FUNCTION) {
305 						if (op_array->static_variables) {
306 							HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
307 							if (ht) {
308 								zend_array_release(ht);
309 								ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
310 							}
311 						}
312 					}
313 				} ZEND_HASH_FOREACH_END();
314 			}
315 		} ZEND_HASH_FOREACH_END();
316 
317 		/* Also release error and exception handlers, which may hold objects. */
318 		if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
319 			zval_ptr_dtor(&EG(user_error_handler));
320 			ZVAL_UNDEF(&EG(user_error_handler));
321 		}
322 
323 		if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
324 			zval_ptr_dtor(&EG(user_exception_handler));
325 			ZVAL_UNDEF(&EG(user_exception_handler));
326 		}
327 
328 		zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1);
329 		zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
330 		zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
331 
332 #if ZEND_DEBUG
333 		if (!CG(unclean_shutdown)) {
334 			gc_collect_cycles();
335 		}
336 #endif
337 	}
338 
339 	zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown);
340 
341 	zend_weakrefs_shutdown();
342 
343 	zend_try {
344 		zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
345 	} zend_end_try();
346 
347 	if (fast_shutdown) {
348 		/* Fast Request Shutdown
349 		 * =====================
350 		 * Zend Memory Manager frees memory by its own. We don't have to free
351 		 * each allocated block separately.
352 		 */
353 		zend_hash_discard(EG(zend_constants), EG(persistent_constants_count));
354 		zend_hash_discard(EG(function_table), EG(persistent_functions_count));
355 		zend_hash_discard(EG(class_table), EG(persistent_classes_count));
356 		zend_cleanup_internal_classes();
357 	} else {
358 		zend_vm_stack_destroy();
359 
360 		if (EG(full_tables_cleanup)) {
361 			zend_hash_reverse_apply(EG(zend_constants), clean_non_persistent_constant_full);
362 			zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function_full);
363 			zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class_full);
364 		} else {
365 			ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(zend_constants), key, zv) {
366 				zend_constant *c = Z_PTR_P(zv);
367 				if (_idx == EG(persistent_constants_count)) {
368 					break;
369 				}
370 				zval_ptr_dtor_nogc(&c->value);
371 				if (c->name) {
372 					zend_string_release_ex(c->name, 0);
373 				}
374 				efree(c);
375 				zend_string_release_ex(key, 0);
376 			} ZEND_HASH_FOREACH_END_DEL();
377 
378 			ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(function_table), key, zv) {
379 				zend_function *func = Z_PTR_P(zv);
380 				if (_idx == EG(persistent_functions_count)) {
381 					break;
382 				}
383 				destroy_op_array(&func->op_array);
384 				zend_string_release_ex(key, 0);
385 			} ZEND_HASH_FOREACH_END_DEL();
386 
387 			ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) {
388 				if (_idx == EG(persistent_classes_count)) {
389 					break;
390 				}
391 				destroy_zend_class(zv);
392 				zend_string_release_ex(key, 0);
393 			} ZEND_HASH_FOREACH_END_DEL();
394 		}
395 
396 		while (EG(symtable_cache_ptr) > EG(symtable_cache)) {
397 			EG(symtable_cache_ptr)--;
398 			zend_hash_destroy(*EG(symtable_cache_ptr));
399 			FREE_HASHTABLE(*EG(symtable_cache_ptr));
400 		}
401 
402 		zend_hash_destroy(&EG(included_files));
403 
404 		zend_stack_destroy(&EG(user_error_handlers_error_reporting));
405 		zend_stack_destroy(&EG(user_error_handlers));
406 		zend_stack_destroy(&EG(user_exception_handlers));
407 		zend_objects_store_destroy(&EG(objects_store));
408 		if (EG(in_autoload)) {
409 			zend_hash_destroy(EG(in_autoload));
410 			FREE_HASHTABLE(EG(in_autoload));
411 		}
412 
413 		if (EG(ht_iterators) != EG(ht_iterators_slots)) {
414 			efree(EG(ht_iterators));
415 		}
416 	}
417 
418 #if ZEND_DEBUG
419 	if (EG(ht_iterators_used) && !CG(unclean_shutdown)) {
420 		zend_error(E_WARNING, "Leaked %" PRIu32 " hashtable iterators", EG(ht_iterators_used));
421 	}
422 #endif
423 
424 	/* Check whether anyone is hogging the trampoline. */
425 	ZEND_ASSERT(EG(trampoline).common.function_name == NULL || CG(unclean_shutdown));
426 
427 	EG(ht_iterators_used) = 0;
428 
429 	zend_shutdown_fpu();
430 }
431 /* }}} */
432 
433 /* return class name and "::" or "". */
get_active_class_name(const char ** space)434 ZEND_API const char *get_active_class_name(const char **space) /* {{{ */
435 {
436 	zend_function *func;
437 
438 	if (!zend_is_executing()) {
439 		if (space) {
440 			*space = "";
441 		}
442 		return "";
443 	}
444 
445 	func = EG(current_execute_data)->func;
446 
447 	switch (func->type) {
448 		case ZEND_USER_FUNCTION:
449 		case ZEND_INTERNAL_FUNCTION:
450 		{
451 			zend_class_entry *ce = func->common.scope;
452 
453 			if (space) {
454 				*space = ce ? "::" : "";
455 			}
456 			return ce ? ZSTR_VAL(ce->name) : "";
457 		}
458 		default:
459 			if (space) {
460 				*space = "";
461 			}
462 			return "";
463 	}
464 }
465 /* }}} */
466 
get_active_function_name(void)467 ZEND_API const char *get_active_function_name(void) /* {{{ */
468 {
469 	zend_function *func;
470 
471 	if (!zend_is_executing()) {
472 		return NULL;
473 	}
474 
475 	func = EG(current_execute_data)->func;
476 
477 	switch (func->type) {
478 		case ZEND_USER_FUNCTION: {
479 				zend_string *function_name = func->common.function_name;
480 
481 				if (function_name) {
482 					return ZSTR_VAL(function_name);
483 				} else {
484 					return "main";
485 				}
486 			}
487 			break;
488 		case ZEND_INTERNAL_FUNCTION:
489 			return ZSTR_VAL(func->common.function_name);
490 			break;
491 		default:
492 			return NULL;
493 	}
494 }
495 /* }}} */
496 
get_active_function_or_method_name(void)497 ZEND_API zend_string *get_active_function_or_method_name(void) /* {{{ */
498 {
499 	ZEND_ASSERT(zend_is_executing());
500 
501 	return get_function_or_method_name(EG(current_execute_data)->func);
502 }
503 /* }}} */
504 
get_function_or_method_name(const zend_function * func)505 ZEND_API zend_string *get_function_or_method_name(const zend_function *func) /* {{{ */
506 {
507 	if (func->common.scope && func->common.function_name) {
508 		return zend_create_member_string(func->common.scope->name, func->common.function_name);
509 	}
510 
511 	return func->common.function_name ? zend_string_copy(func->common.function_name) : zend_string_init("main", sizeof("main") - 1, 0);
512 }
513 /* }}} */
514 
get_active_function_arg_name(uint32_t arg_num)515 ZEND_API const char *get_active_function_arg_name(uint32_t arg_num) /* {{{ */
516 {
517 	zend_function *func;
518 
519 	if (!zend_is_executing()) {
520 		return NULL;
521 	}
522 
523 	func = EG(current_execute_data)->func;
524 
525 	return get_function_arg_name(func, arg_num);
526 }
527 /* }}} */
528 
get_function_arg_name(const zend_function * func,uint32_t arg_num)529 ZEND_API const char *get_function_arg_name(const zend_function *func, uint32_t arg_num) /* {{{ */
530 {
531 	if (!func || func->common.num_args < arg_num) {
532 		return NULL;
533 	}
534 
535 	if (func->type == ZEND_USER_FUNCTION || (func->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
536 		return ZSTR_VAL(func->common.arg_info[arg_num - 1].name);
537 	} else {
538 		return ((zend_internal_arg_info*) func->common.arg_info)[arg_num - 1].name;
539 	}
540 }
541 /* }}} */
542 
zend_get_executed_filename(void)543 ZEND_API const char *zend_get_executed_filename(void) /* {{{ */
544 {
545 	zend_execute_data *ex = EG(current_execute_data);
546 
547 	while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
548 		ex = ex->prev_execute_data;
549 	}
550 	if (ex) {
551 		return ZSTR_VAL(ex->func->op_array.filename);
552 	} else {
553 		return "[no active file]";
554 	}
555 }
556 /* }}} */
557 
zend_get_executed_filename_ex(void)558 ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */
559 {
560 	zend_execute_data *ex = EG(current_execute_data);
561 
562 	while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
563 		ex = ex->prev_execute_data;
564 	}
565 	if (ex) {
566 		return ex->func->op_array.filename;
567 	} else {
568 		return NULL;
569 	}
570 }
571 /* }}} */
572 
zend_get_executed_lineno(void)573 ZEND_API uint32_t zend_get_executed_lineno(void) /* {{{ */
574 {
575 	zend_execute_data *ex = EG(current_execute_data);
576 
577 	while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
578 		ex = ex->prev_execute_data;
579 	}
580 	if (ex) {
581 		if (EG(exception) && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
582 		    ex->opline->lineno == 0 && EG(opline_before_exception)) {
583 			return EG(opline_before_exception)->lineno;
584 		}
585 		return ex->opline->lineno;
586 	} else {
587 		return 0;
588 	}
589 }
590 /* }}} */
591 
zend_get_executed_scope(void)592 ZEND_API zend_class_entry *zend_get_executed_scope(void) /* {{{ */
593 {
594 	zend_execute_data *ex = EG(current_execute_data);
595 
596 	while (1) {
597 		if (!ex) {
598 			return NULL;
599 		} else if (ex->func && (ZEND_USER_CODE(ex->func->type) || ex->func->common.scope)) {
600 			return ex->func->common.scope;
601 		}
602 		ex = ex->prev_execute_data;
603 	}
604 }
605 /* }}} */
606 
zend_is_executing(void)607 ZEND_API zend_bool zend_is_executing(void) /* {{{ */
608 {
609 	return EG(current_execute_data) != 0;
610 }
611 /* }}} */
612 
zval_update_constant_ex(zval * p,zend_class_entry * scope)613 ZEND_API zend_result zval_update_constant_ex(zval *p, zend_class_entry *scope) /* {{{ */
614 {
615 	if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
616 		zend_ast *ast = Z_ASTVAL_P(p);
617 
618 		if (ast->kind == ZEND_AST_CONSTANT) {
619 			zend_string *name = zend_ast_get_constant_name(ast);
620 			zval *zv = zend_get_constant_ex(name, scope, ast->attr);
621 			if (UNEXPECTED(zv == NULL)) {
622 				return FAILURE;
623 			}
624 
625 			zval_ptr_dtor_nogc(p);
626 			ZVAL_COPY_OR_DUP(p, zv);
627 		} else {
628 			zval tmp;
629 
630 			if (UNEXPECTED(zend_ast_evaluate(&tmp, ast, scope) != SUCCESS)) {
631 				return FAILURE;
632 			}
633 			zval_ptr_dtor_nogc(p);
634 			ZVAL_COPY_VALUE(p, &tmp);
635 		}
636 	}
637 	return SUCCESS;
638 }
639 /* }}} */
640 
zval_update_constant(zval * pp)641 ZEND_API zend_result zval_update_constant(zval *pp) /* {{{ */
642 {
643 	return zval_update_constant_ex(pp, EG(current_execute_data) ? zend_get_executed_scope() : CG(active_class_entry));
644 }
645 /* }}} */
646 
_call_user_function_impl(zval * object,zval * function_name,zval * retval_ptr,uint32_t param_count,zval params[],HashTable * named_params)647 zend_result _call_user_function_impl(zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], HashTable *named_params) /* {{{ */
648 {
649 	zend_fcall_info fci;
650 
651 	fci.size = sizeof(fci);
652 	fci.object = object ? Z_OBJ_P(object) : NULL;
653 	ZVAL_COPY_VALUE(&fci.function_name, function_name);
654 	fci.retval = retval_ptr;
655 	fci.param_count = param_count;
656 	fci.params = params;
657 	fci.named_params = named_params;
658 
659 	return zend_call_function(&fci, NULL);
660 }
661 /* }}} */
662 
zend_call_function(zend_fcall_info * fci,zend_fcall_info_cache * fci_cache)663 zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /* {{{ */
664 {
665 	uint32_t i;
666 	zend_execute_data *call, dummy_execute_data;
667 	zend_fcall_info_cache fci_cache_local;
668 	zend_function *func;
669 	uint32_t call_info;
670 	void *object_or_called_scope;
671 	zend_class_entry *orig_fake_scope;
672 
673 	ZVAL_UNDEF(fci->retval);
674 
675 	if (!EG(active)) {
676 		return FAILURE; /* executor is already inactive */
677 	}
678 
679 	if (EG(exception)) {
680 		return FAILURE; /* we would result in an instable executor otherwise */
681 	}
682 
683 	ZEND_ASSERT(fci->size == sizeof(zend_fcall_info));
684 
685 	/* Initialize execute_data */
686 	if (!EG(current_execute_data)) {
687 		/* This only happens when we're called outside any execute()'s
688 		 * It shouldn't be strictly necessary to NULL execute_data out,
689 		 * but it may make bugs easier to spot
690 		 */
691 		memset(&dummy_execute_data, 0, sizeof(zend_execute_data));
692 		EG(current_execute_data) = &dummy_execute_data;
693 	} else if (EG(current_execute_data)->func &&
694 	           ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
695 	           EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL &&
696 	           EG(current_execute_data)->opline->opcode != ZEND_DO_ICALL &&
697 	           EG(current_execute_data)->opline->opcode != ZEND_DO_UCALL &&
698 	           EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL_BY_NAME) {
699 		/* Insert fake frame in case of include or magic calls */
700 		dummy_execute_data = *EG(current_execute_data);
701 		dummy_execute_data.prev_execute_data = EG(current_execute_data);
702 		dummy_execute_data.call = NULL;
703 		dummy_execute_data.opline = NULL;
704 		dummy_execute_data.func = NULL;
705 		EG(current_execute_data) = &dummy_execute_data;
706 	}
707 
708 	if (!fci_cache || !fci_cache->function_handler) {
709 		char *error = NULL;
710 
711 		if (!fci_cache) {
712 			fci_cache = &fci_cache_local;
713 		}
714 
715 		if (!zend_is_callable_ex(&fci->function_name, fci->object, IS_CALLABLE_CHECK_SILENT, NULL, fci_cache, &error)) {
716 			if (error) {
717 				zend_string *callable_name
718 					= zend_get_callable_name_ex(&fci->function_name, fci->object);
719 				zend_error(E_WARNING, "Invalid callback %s, %s", ZSTR_VAL(callable_name), error);
720 				efree(error);
721 				zend_string_release_ex(callable_name, 0);
722 			}
723 			if (EG(current_execute_data) == &dummy_execute_data) {
724 				EG(current_execute_data) = dummy_execute_data.prev_execute_data;
725 			}
726 			return FAILURE;
727 		}
728 
729 		ZEND_ASSERT(!error);
730 	}
731 
732 	func = fci_cache->function_handler;
733 	if ((func->common.fn_flags & ZEND_ACC_STATIC) || !fci_cache->object) {
734 		fci->object = NULL;
735 		object_or_called_scope = fci_cache->called_scope;
736 		call_info = ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC;
737 	} else {
738 		fci->object = fci_cache->object;
739 		object_or_called_scope = fci->object;
740 		call_info = ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC | ZEND_CALL_HAS_THIS;
741 	}
742 
743 	call = zend_vm_stack_push_call_frame(call_info,
744 		func, fci->param_count, object_or_called_scope);
745 
746 	if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_DEPRECATED)) {
747 		zend_deprecated_function(func);
748 
749 		if (UNEXPECTED(EG(exception))) {
750 			zend_vm_stack_free_call_frame(call);
751 			if (EG(current_execute_data) == &dummy_execute_data) {
752 				EG(current_execute_data) = dummy_execute_data.prev_execute_data;
753 				zend_rethrow_exception(EG(current_execute_data));
754 			}
755 			return FAILURE;
756 		}
757 	}
758 
759 	for (i=0; i<fci->param_count; i++) {
760 		zval *param = ZEND_CALL_ARG(call, i+1);
761 		zval *arg = &fci->params[i];
762 		zend_bool must_wrap = 0;
763 		if (UNEXPECTED(Z_ISUNDEF_P(arg))) {
764 			/* Allow forwarding undef slots. This is only used by Closure::__invoke(). */
765 			ZVAL_UNDEF(param);
766 			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_MAY_HAVE_UNDEF);
767 			continue;
768 		}
769 
770 		if (ARG_SHOULD_BE_SENT_BY_REF(func, i + 1)) {
771 			if (UNEXPECTED(!Z_ISREF_P(arg))) {
772 				if (!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
773 					/* By-value send is not allowed -- emit a warning,
774 					 * and perform the call with the value wrapped in a reference. */
775 					zend_param_must_be_ref(func, i + 1);
776 					must_wrap = 1;
777 					if (UNEXPECTED(EG(exception))) {
778 						ZEND_CALL_NUM_ARGS(call) = i;
779 cleanup_args:
780 						zend_vm_stack_free_args(call);
781 						zend_vm_stack_free_call_frame(call);
782 						if (EG(current_execute_data) == &dummy_execute_data) {
783 							EG(current_execute_data) = dummy_execute_data.prev_execute_data;
784 						}
785 						return FAILURE;
786 					}
787 				}
788 			}
789 		} else {
790 			if (Z_ISREF_P(arg) &&
791 			    !(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
792 				/* don't separate references for __call */
793 				arg = Z_REFVAL_P(arg);
794 			}
795 		}
796 
797 		if (EXPECTED(!must_wrap)) {
798 			ZVAL_COPY(param, arg);
799 		} else {
800 			Z_TRY_ADDREF_P(arg);
801 			ZVAL_NEW_REF(param, arg);
802 		}
803 	}
804 
805 	if (fci->named_params) {
806 		zend_string *name;
807 		zval *arg;
808 		uint32_t arg_num = ZEND_CALL_NUM_ARGS(call) + 1;
809 		zend_bool have_named_params = 0;
810 		ZEND_HASH_FOREACH_STR_KEY_VAL(fci->named_params, name, arg) {
811 			zend_bool must_wrap = 0;
812 			zval *target;
813 			if (name) {
814 				void *cache_slot[2] = {NULL, NULL};
815 				have_named_params = 1;
816 				target = zend_handle_named_arg(&call, name, &arg_num, cache_slot);
817 				if (!target) {
818 					goto cleanup_args;
819 				}
820 			} else {
821 				if (have_named_params) {
822 					zend_throw_error(NULL,
823 						"Cannot use positional argument after named argument");
824 					goto cleanup_args;
825 				}
826 
827 				zend_vm_stack_extend_call_frame(&call, arg_num - 1, 1);
828 				target = ZEND_CALL_ARG(call, arg_num);
829 			}
830 
831 			if (ARG_SHOULD_BE_SENT_BY_REF(func, arg_num)) {
832 				if (UNEXPECTED(!Z_ISREF_P(arg))) {
833 					if (!ARG_MAY_BE_SENT_BY_REF(func, arg_num)) {
834 						/* By-value send is not allowed -- emit a warning,
835 						 * and perform the call with the value wrapped in a reference. */
836 						zend_param_must_be_ref(func, arg_num);
837 						must_wrap = 1;
838 						if (UNEXPECTED(EG(exception))) {
839 							goto cleanup_args;
840 						}
841 					}
842 				}
843 			} else {
844 				if (Z_ISREF_P(arg) &&
845 					!(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
846 					/* don't separate references for __call */
847 					arg = Z_REFVAL_P(arg);
848 				}
849 			}
850 
851 			if (EXPECTED(!must_wrap)) {
852 				ZVAL_COPY(target, arg);
853 			} else {
854 				Z_TRY_ADDREF_P(arg);
855 				ZVAL_NEW_REF(target, arg);
856 			}
857 			if (!name) {
858 				ZEND_CALL_NUM_ARGS(call)++;
859 				arg_num++;
860 			}
861 		} ZEND_HASH_FOREACH_END();
862 	}
863 
864 	if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_MAY_HAVE_UNDEF)) {
865 		if (zend_handle_undef_args(call) == FAILURE) {
866 			zend_vm_stack_free_args(call);
867 			zend_vm_stack_free_call_frame(call);
868 			if (EG(current_execute_data) == &dummy_execute_data) {
869 				EG(current_execute_data) = dummy_execute_data.prev_execute_data;
870 			}
871 			return SUCCESS;
872 		}
873 	}
874 
875 	if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
876 		uint32_t call_info;
877 
878 		GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
879 		call_info = ZEND_CALL_CLOSURE;
880 		if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
881 			call_info |= ZEND_CALL_FAKE_CLOSURE;
882 		}
883 		ZEND_ADD_CALL_FLAG(call, call_info);
884 	}
885 
886 	orig_fake_scope = EG(fake_scope);
887 	EG(fake_scope) = NULL;
888 	if (func->type == ZEND_USER_FUNCTION) {
889 		int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
890 		const zend_op *current_opline_before_exception = EG(opline_before_exception);
891 		uint32_t orig_jit_trace_num = EG(jit_trace_num);
892 
893 		zend_init_func_execute_data(call, &func->op_array, fci->retval);
894 		ZEND_OBSERVER_FCALL_BEGIN(call);
895 		zend_execute_ex(call);
896 		EG(jit_trace_num) = orig_jit_trace_num;
897 		EG(opline_before_exception) = current_opline_before_exception;
898 		if (call_via_handler) {
899 			/* We must re-initialize function again */
900 			fci_cache->function_handler = NULL;
901 		}
902 	} else {
903 		int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
904 
905 		ZEND_ASSERT(func->type == ZEND_INTERNAL_FUNCTION);
906 		ZVAL_NULL(fci->retval);
907 		call->prev_execute_data = EG(current_execute_data);
908 		EG(current_execute_data) = call;
909 		if (EXPECTED(zend_execute_internal == NULL)) {
910 			/* saves one function call if zend_execute_internal is not used */
911 			func->internal_function.handler(call, fci->retval);
912 		} else {
913 			zend_execute_internal(call, fci->retval);
914 		}
915 		EG(current_execute_data) = call->prev_execute_data;
916 		zend_vm_stack_free_args(call);
917 		if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
918 			zend_array_release(call->extra_named_params);
919 		}
920 
921 		if (EG(exception)) {
922 			zval_ptr_dtor(fci->retval);
923 			ZVAL_UNDEF(fci->retval);
924 		}
925 
926 		if (call_via_handler) {
927 			/* We must re-initialize function again */
928 			fci_cache->function_handler = NULL;
929 		}
930 
931 		/* This flag is regularly checked while running user functions, but not internal
932 		 * So see whether interrupt flag was set while the function was running... */
933 		if (EG(vm_interrupt)) {
934 			EG(vm_interrupt) = 0;
935 			if (EG(timed_out)) {
936 				zend_timeout();
937 			} else if (zend_interrupt_function) {
938 				zend_interrupt_function(EG(current_execute_data));
939 			}
940 		}
941 	}
942 	EG(fake_scope) = orig_fake_scope;
943 
944 	zend_vm_stack_free_call_frame(call);
945 
946 	if (EG(current_execute_data) == &dummy_execute_data) {
947 		EG(current_execute_data) = dummy_execute_data.prev_execute_data;
948 	}
949 
950 	if (UNEXPECTED(EG(exception))) {
951 		if (UNEXPECTED(!EG(current_execute_data))) {
952 			zend_throw_exception_internal(NULL);
953 		} else if (EG(current_execute_data)->func &&
954 		           ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
955 			zend_rethrow_exception(EG(current_execute_data));
956 		}
957 	}
958 
959 	return SUCCESS;
960 }
961 /* }}} */
962 
zend_call_known_function(zend_function * fn,zend_object * object,zend_class_entry * called_scope,zval * retval_ptr,uint32_t param_count,zval * params,HashTable * named_params)963 ZEND_API void zend_call_known_function(
964 		zend_function *fn, zend_object *object, zend_class_entry *called_scope, zval *retval_ptr,
965 		uint32_t param_count, zval *params, HashTable *named_params)
966 {
967 	zval retval;
968 	zend_fcall_info fci;
969 	zend_fcall_info_cache fcic;
970 
971 	ZEND_ASSERT(fn && "zend_function must be passed!");
972 
973 	fci.size = sizeof(fci);
974 	fci.object = object;
975 	fci.retval = retval_ptr ? retval_ptr : &retval;
976 	fci.param_count = param_count;
977 	fci.params = params;
978 	fci.named_params = named_params;
979 	ZVAL_UNDEF(&fci.function_name); /* Unused */
980 
981 	fcic.function_handler = fn;
982 	fcic.object = object;
983 	fcic.called_scope = called_scope;
984 
985 	zend_result result = zend_call_function(&fci, &fcic);
986 	if (UNEXPECTED(result == FAILURE)) {
987 		if (!EG(exception)) {
988 			zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s",
989 				fn->common.scope ? ZSTR_VAL(fn->common.scope->name) : "",
990 				fn->common.scope ? "::" : "", ZSTR_VAL(fn->common.function_name));
991 		}
992 	}
993 
994 	if (!retval_ptr) {
995 		zval_ptr_dtor(&retval);
996 	}
997 }
998 
zend_call_known_instance_method_with_2_params(zend_function * fn,zend_object * object,zval * retval_ptr,zval * param1,zval * param2)999 ZEND_API void zend_call_known_instance_method_with_2_params(
1000 		zend_function *fn, zend_object *object, zval *retval_ptr, zval *param1, zval *param2)
1001 {
1002 	zval params[2];
1003 	ZVAL_COPY_VALUE(&params[0], param1);
1004 	ZVAL_COPY_VALUE(&params[1], param2);
1005 	zend_call_known_instance_method(fn, object, retval_ptr, 2, params);
1006 }
1007 
1008 /* 0-9 a-z A-Z _ \ 0x80-0xff */
1009 static const uint32_t valid_chars[8] = {
1010 	0x00000000,
1011 	0x03ff0000,
1012 	0x97fffffe,
1013 	0x07fffffe,
1014 	0xffffffff,
1015 	0xffffffff,
1016 	0xffffffff,
1017 	0xffffffff,
1018 };
1019 
zend_is_valid_class_name(zend_string * name)1020 ZEND_API zend_bool zend_is_valid_class_name(zend_string *name) {
1021 	for (size_t i = 0; i < ZSTR_LEN(name); i++) {
1022 		unsigned char c = ZSTR_VAL(name)[i];
1023 		if (!ZEND_BIT_TEST(valid_chars, c)) {
1024 			return 0;
1025 		}
1026 	}
1027 	return 1;
1028 }
1029 
zend_lookup_class_ex(zend_string * name,zend_string * key,uint32_t flags)1030 ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *key, uint32_t flags) /* {{{ */
1031 {
1032 	zend_class_entry *ce = NULL;
1033 	zval *zv;
1034 	zend_string *lc_name;
1035 	zend_string *autoload_name;
1036 
1037 	if (key) {
1038 		lc_name = key;
1039 	} else {
1040 		if (name == NULL || !ZSTR_LEN(name)) {
1041 			return NULL;
1042 		}
1043 
1044 		if (ZSTR_VAL(name)[0] == '\\') {
1045 			lc_name = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
1046 			zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
1047 		} else {
1048 			lc_name = zend_string_tolower(name);
1049 		}
1050 	}
1051 
1052 	zv = zend_hash_find(EG(class_table), lc_name);
1053 	if (zv) {
1054 		if (!key) {
1055 			zend_string_release_ex(lc_name, 0);
1056 		}
1057 		ce = (zend_class_entry*)Z_PTR_P(zv);
1058 		if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_LINKED))) {
1059 			if ((flags & ZEND_FETCH_CLASS_ALLOW_UNLINKED) ||
1060 				((flags & ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED) &&
1061 					(ce->ce_flags & ZEND_ACC_NEARLY_LINKED))) {
1062 				ce->ce_flags |= ZEND_ACC_HAS_UNLINKED_USES;
1063 				return ce;
1064 			}
1065 			return NULL;
1066 		}
1067 		return ce;
1068 	}
1069 
1070 	/* The compiler is not-reentrant. Make sure we autoload only during run-time. */
1071 	if ((flags & ZEND_FETCH_CLASS_NO_AUTOLOAD) || zend_is_compiling()) {
1072 		if (!key) {
1073 			zend_string_release_ex(lc_name, 0);
1074 		}
1075 		return NULL;
1076 	}
1077 
1078 	if (!zend_autoload) {
1079 		if (!key) {
1080 			zend_string_release_ex(lc_name, 0);
1081 		}
1082 		return NULL;
1083 	}
1084 
1085 	/* Verify class name before passing it to the autoloader. */
1086 	if (!key && !zend_is_valid_class_name(name)) {
1087 		zend_string_release_ex(lc_name, 0);
1088 		return NULL;
1089 	}
1090 
1091 	if (EG(in_autoload) == NULL) {
1092 		ALLOC_HASHTABLE(EG(in_autoload));
1093 		zend_hash_init(EG(in_autoload), 8, NULL, NULL, 0);
1094 	}
1095 
1096 	if (zend_hash_add_empty_element(EG(in_autoload), lc_name) == NULL) {
1097 		if (!key) {
1098 			zend_string_release_ex(lc_name, 0);
1099 		}
1100 		return NULL;
1101 	}
1102 
1103 	if (ZSTR_VAL(name)[0] == '\\') {
1104 		autoload_name = zend_string_init(ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1, 0);
1105 	} else {
1106 		autoload_name = zend_string_copy(name);
1107 	}
1108 
1109 	zend_exception_save();
1110 	ce = zend_autoload(autoload_name, lc_name);
1111 	zend_exception_restore();
1112 
1113 	zend_string_release_ex(autoload_name, 0);
1114 	zend_hash_del(EG(in_autoload), lc_name);
1115 
1116 	if (!key) {
1117 		zend_string_release_ex(lc_name, 0);
1118 	}
1119 	return ce;
1120 }
1121 /* }}} */
1122 
zend_lookup_class(zend_string * name)1123 ZEND_API zend_class_entry *zend_lookup_class(zend_string *name) /* {{{ */
1124 {
1125 	return zend_lookup_class_ex(name, NULL, 0);
1126 }
1127 /* }}} */
1128 
zend_get_called_scope(zend_execute_data * ex)1129 ZEND_API zend_class_entry *zend_get_called_scope(zend_execute_data *ex) /* {{{ */
1130 {
1131 	while (ex) {
1132 		if (Z_TYPE(ex->This) == IS_OBJECT) {
1133 			return Z_OBJCE(ex->This);
1134 		} else if (Z_CE(ex->This)) {
1135 			return Z_CE(ex->This);
1136 		} else if (ex->func) {
1137 			if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
1138 				return NULL;
1139 			}
1140 		}
1141 		ex = ex->prev_execute_data;
1142 	}
1143 	return NULL;
1144 }
1145 /* }}} */
1146 
zend_get_this_object(zend_execute_data * ex)1147 ZEND_API zend_object *zend_get_this_object(zend_execute_data *ex) /* {{{ */
1148 {
1149 	while (ex) {
1150 		if (Z_TYPE(ex->This) == IS_OBJECT) {
1151 			return Z_OBJ(ex->This);
1152 		} else if (ex->func) {
1153 			if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
1154 				return NULL;
1155 			}
1156 		}
1157 		ex = ex->prev_execute_data;
1158 	}
1159 	return NULL;
1160 }
1161 /* }}} */
1162 
zend_eval_stringl(const char * str,size_t str_len,zval * retval_ptr,const char * string_name)1163 ZEND_API zend_result zend_eval_stringl(const char *str, size_t str_len, zval *retval_ptr, const char *string_name) /* {{{ */
1164 {
1165 	zend_op_array *new_op_array;
1166 	uint32_t original_compiler_options;
1167 	zend_result retval;
1168 	zend_string *code_str;
1169 
1170 	if (retval_ptr) {
1171 		code_str = zend_string_concat3(
1172 			"return ", sizeof("return ")-1, str, str_len, ";", sizeof(";")-1);
1173 	} else {
1174 		code_str = zend_string_init(str, str_len, 0);
1175 	}
1176 
1177 	/*printf("Evaluating '%s'\n", pv.value.str.val);*/
1178 
1179 	original_compiler_options = CG(compiler_options);
1180 	CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
1181 	new_op_array = zend_compile_string(code_str, string_name);
1182 	CG(compiler_options) = original_compiler_options;
1183 
1184 	if (new_op_array) {
1185 		zval local_retval;
1186 
1187 		EG(no_extensions)=1;
1188 
1189 		new_op_array->scope = zend_get_executed_scope();
1190 
1191 		zend_try {
1192 			ZVAL_UNDEF(&local_retval);
1193 			zend_execute(new_op_array, &local_retval);
1194 		} zend_catch {
1195 			destroy_op_array(new_op_array);
1196 			efree_size(new_op_array, sizeof(zend_op_array));
1197 			zend_bailout();
1198 		} zend_end_try();
1199 
1200 		if (Z_TYPE(local_retval) != IS_UNDEF) {
1201 			if (retval_ptr) {
1202 				ZVAL_COPY_VALUE(retval_ptr, &local_retval);
1203 			} else {
1204 				zval_ptr_dtor(&local_retval);
1205 			}
1206 		} else {
1207 			if (retval_ptr) {
1208 				ZVAL_NULL(retval_ptr);
1209 			}
1210 		}
1211 
1212 		EG(no_extensions)=0;
1213 		destroy_op_array(new_op_array);
1214 		efree_size(new_op_array, sizeof(zend_op_array));
1215 		retval = SUCCESS;
1216 	} else {
1217 		retval = FAILURE;
1218 	}
1219 	zend_string_release(code_str);
1220 	return retval;
1221 }
1222 /* }}} */
1223 
zend_eval_string(const char * str,zval * retval_ptr,const char * string_name)1224 ZEND_API zend_result zend_eval_string(const char *str, zval *retval_ptr, const char *string_name) /* {{{ */
1225 {
1226 	return zend_eval_stringl(str, strlen(str), retval_ptr, string_name);
1227 }
1228 /* }}} */
1229 
zend_eval_stringl_ex(const char * str,size_t str_len,zval * retval_ptr,const char * string_name,bool handle_exceptions)1230 ZEND_API zend_result zend_eval_stringl_ex(const char *str, size_t str_len, zval *retval_ptr, const char *string_name, bool handle_exceptions) /* {{{ */
1231 {
1232 	zend_result result;
1233 
1234 	result = zend_eval_stringl(str, str_len, retval_ptr, string_name);
1235 	if (handle_exceptions && EG(exception)) {
1236 		result = zend_exception_error(EG(exception), E_ERROR);
1237 	}
1238 	return result;
1239 }
1240 /* }}} */
1241 
zend_eval_string_ex(const char * str,zval * retval_ptr,const char * string_name,bool handle_exceptions)1242 ZEND_API zend_result zend_eval_string_ex(const char *str, zval *retval_ptr, const char *string_name, bool handle_exceptions) /* {{{ */
1243 {
1244 	return zend_eval_stringl_ex(str, strlen(str), retval_ptr, string_name, handle_exceptions);
1245 }
1246 /* }}} */
1247 
1248 static void zend_set_timeout_ex(zend_long seconds, bool reset_signals);
1249 
zend_timeout(void)1250 ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */
1251 {
1252 #if defined(PHP_WIN32)
1253 # ifndef ZTS
1254 	/* No action is needed if we're timed out because zero seconds are
1255 	   just ignored. Also, the hard timeout needs to be respected. If the
1256 	   timer is not restarted properly, it could hang in the shutdown
1257 	   function. */
1258 	if (EG(hard_timeout) > 0) {
1259 		EG(timed_out) = 0;
1260 		zend_set_timeout_ex(EG(hard_timeout), 1);
1261 		/* XXX Abused, introduce an additional flag if the value needs to be kept. */
1262 		EG(hard_timeout) = 0;
1263 	}
1264 # endif
1265 #else
1266 	EG(timed_out) = 0;
1267 	zend_set_timeout_ex(0, 1);
1268 #endif
1269 
1270 	zend_error_noreturn(E_ERROR, "Maximum execution time of " ZEND_LONG_FMT " second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
1271 }
1272 /* }}} */
1273 
1274 #ifndef ZEND_WIN32
zend_timeout_handler(int dummy)1275 static void zend_timeout_handler(int dummy) /* {{{ */
1276 {
1277 #ifndef ZTS
1278     if (EG(timed_out)) {
1279 		/* Die on hard timeout */
1280 		const char *error_filename = NULL;
1281 		uint32_t error_lineno = 0;
1282 		char log_buffer[2048];
1283 		int output_len = 0;
1284 
1285 		if (zend_is_compiling()) {
1286 			error_filename = ZSTR_VAL(zend_get_compiled_filename());
1287 			error_lineno = zend_get_compiled_lineno();
1288 		} else if (zend_is_executing()) {
1289 			error_filename = zend_get_executed_filename();
1290 			if (error_filename[0] == '[') { /* [no active file] */
1291 				error_filename = NULL;
1292 				error_lineno = 0;
1293 			} else {
1294 				error_lineno = zend_get_executed_lineno();
1295 			}
1296 		}
1297 		if (!error_filename) {
1298 			error_filename = "Unknown";
1299 		}
1300 
1301 		output_len = snprintf(log_buffer, sizeof(log_buffer), "\nFatal error: Maximum execution time of " ZEND_LONG_FMT "+" ZEND_LONG_FMT " seconds exceeded (terminated) in %s on line %d\n", EG(timeout_seconds), EG(hard_timeout), error_filename, error_lineno);
1302 		if (output_len > 0) {
1303 			zend_quiet_write(2, log_buffer, MIN(output_len, sizeof(log_buffer)));
1304 		}
1305 		_exit(124);
1306     }
1307 #endif
1308 
1309 	if (zend_on_timeout) {
1310 		zend_on_timeout(EG(timeout_seconds));
1311 	}
1312 
1313 	EG(timed_out) = 1;
1314 	EG(vm_interrupt) = 1;
1315 
1316 #ifndef ZTS
1317 	if (EG(hard_timeout) > 0) {
1318 		/* Set hard timeout */
1319 		zend_set_timeout_ex(EG(hard_timeout), 1);
1320 	}
1321 #endif
1322 }
1323 /* }}} */
1324 #endif
1325 
1326 #ifdef ZEND_WIN32
tq_timer_cb(PVOID arg,BOOLEAN timed_out)1327 VOID CALLBACK tq_timer_cb(PVOID arg, BOOLEAN timed_out)
1328 {
1329 	zend_executor_globals *eg;
1330 
1331 	/* The doc states it'll be always true, however it theoretically
1332 		could be FALSE when the thread was signaled. */
1333 	if (!timed_out) {
1334 		return;
1335 	}
1336 
1337 	eg = (zend_executor_globals *)arg;
1338 	eg->timed_out = 1;
1339 	eg->vm_interrupt = 1;
1340 }
1341 #endif
1342 
1343 /* This one doesn't exists on QNX */
1344 #ifndef SIGPROF
1345 #define SIGPROF 27
1346 #endif
1347 
zend_set_timeout_ex(zend_long seconds,bool reset_signals)1348 static void zend_set_timeout_ex(zend_long seconds, bool reset_signals) /* {{{ */
1349 {
1350 #ifdef ZEND_WIN32
1351 	zend_executor_globals *eg;
1352 
1353 	if (!seconds) {
1354 		return;
1355 	}
1356 
1357 	/* Don't use ChangeTimerQueueTimer() as it will not restart an expired
1358 	 * timer, so we could end up with just an ignored timeout. Instead
1359 	 * delete and recreate. */
1360 	if (NULL != tq_timer) {
1361 		if (!DeleteTimerQueueTimer(NULL, tq_timer, INVALID_HANDLE_VALUE)) {
1362 			tq_timer = NULL;
1363 			zend_error_noreturn(E_ERROR, "Could not delete queued timer");
1364 			return;
1365 		}
1366 		tq_timer = NULL;
1367 	}
1368 
1369 	/* XXX passing NULL means the default timer queue provided by the system is used */
1370 	eg = ZEND_MODULE_GLOBALS_BULK(executor);
1371 	if (!CreateTimerQueueTimer(&tq_timer, NULL, (WAITORTIMERCALLBACK)tq_timer_cb, (VOID*)eg, seconds*1000, 0, WT_EXECUTEONLYONCE)) {
1372 		tq_timer = NULL;
1373 		zend_error_noreturn(E_ERROR, "Could not queue new timer");
1374 		return;
1375 	}
1376 #elif defined(HAVE_SETITIMER)
1377 	{
1378 		struct itimerval t_r;		/* timeout requested */
1379 		int signo;
1380 
1381 		if(seconds) {
1382 			t_r.it_value.tv_sec = seconds;
1383 			t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
1384 
1385 # if defined(__CYGWIN__) || defined(__PASE__)
1386 			setitimer(ITIMER_REAL, &t_r, NULL);
1387 		}
1388 		signo = SIGALRM;
1389 # else
1390 			setitimer(ITIMER_PROF, &t_r, NULL);
1391 		}
1392 		signo = SIGPROF;
1393 # endif
1394 
1395 		if (reset_signals) {
1396 # ifdef ZEND_SIGNALS
1397 			zend_signal(signo, zend_timeout_handler);
1398 # else
1399 			sigset_t sigset;
1400 #  ifdef HAVE_SIGACTION
1401 			struct sigaction act;
1402 
1403 			act.sa_handler = zend_timeout_handler;
1404 			sigemptyset(&act.sa_mask);
1405 			act.sa_flags = SA_RESETHAND | SA_NODEFER;
1406 			sigaction(signo, &act, NULL);
1407 #  else
1408 			signal(signo, zend_timeout_handler);
1409 #  endif /* HAVE_SIGACTION */
1410 			sigemptyset(&sigset);
1411 			sigaddset(&sigset, signo);
1412 			sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1413 # endif /* ZEND_SIGNALS */
1414 		}
1415 	}
1416 #endif /* HAVE_SETITIMER */
1417 }
1418 /* }}} */
1419 
zend_set_timeout(zend_long seconds,bool reset_signals)1420 void zend_set_timeout(zend_long seconds, bool reset_signals) /* {{{ */
1421 {
1422 
1423 	EG(timeout_seconds) = seconds;
1424 	zend_set_timeout_ex(seconds, reset_signals);
1425 	EG(timed_out) = 0;
1426 }
1427 /* }}} */
1428 
zend_unset_timeout(void)1429 void zend_unset_timeout(void) /* {{{ */
1430 {
1431 #ifdef ZEND_WIN32
1432 	if (NULL != tq_timer) {
1433 		if (!DeleteTimerQueueTimer(NULL, tq_timer, INVALID_HANDLE_VALUE)) {
1434 			EG(timed_out) = 0;
1435 			tq_timer = NULL;
1436 			zend_error_noreturn(E_ERROR, "Could not delete queued timer");
1437 			return;
1438 		}
1439 		tq_timer = NULL;
1440 	}
1441 #elif defined(HAVE_SETITIMER)
1442 	if (EG(timeout_seconds)) {
1443 		struct itimerval no_timeout;
1444 
1445 		no_timeout.it_value.tv_sec = no_timeout.it_value.tv_usec = no_timeout.it_interval.tv_sec = no_timeout.it_interval.tv_usec = 0;
1446 
1447 # if defined(__CYGWIN__) || defined(__PASE__)
1448 		setitimer(ITIMER_REAL, &no_timeout, NULL);
1449 # else
1450 		setitimer(ITIMER_PROF, &no_timeout, NULL);
1451 # endif
1452 	}
1453 #endif
1454 	EG(timed_out) = 0;
1455 }
1456 /* }}} */
1457 
zend_fetch_class(zend_string * class_name,int fetch_type)1458 zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type) /* {{{ */
1459 {
1460 	zend_class_entry *ce, *scope;
1461 	int fetch_sub_type = fetch_type & ZEND_FETCH_CLASS_MASK;
1462 
1463 check_fetch_type:
1464 	switch (fetch_sub_type) {
1465 		case ZEND_FETCH_CLASS_SELF:
1466 			scope = zend_get_executed_scope();
1467 			if (UNEXPECTED(!scope)) {
1468 				zend_throw_or_error(fetch_type, NULL, "Cannot access \"self\" when no class scope is active");
1469 			}
1470 			return scope;
1471 		case ZEND_FETCH_CLASS_PARENT:
1472 			scope = zend_get_executed_scope();
1473 			if (UNEXPECTED(!scope)) {
1474 				zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when no class scope is active");
1475 				return NULL;
1476 			}
1477 			if (UNEXPECTED(!scope->parent)) {
1478 				zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when current class scope has no parent");
1479 			}
1480 			return scope->parent;
1481 		case ZEND_FETCH_CLASS_STATIC:
1482 			ce = zend_get_called_scope(EG(current_execute_data));
1483 			if (UNEXPECTED(!ce)) {
1484 				zend_throw_or_error(fetch_type, NULL, "Cannot access \"static\" when no class scope is active");
1485 				return NULL;
1486 			}
1487 			return ce;
1488 		case ZEND_FETCH_CLASS_AUTO: {
1489 				fetch_sub_type = zend_get_class_fetch_type(class_name);
1490 				if (UNEXPECTED(fetch_sub_type != ZEND_FETCH_CLASS_DEFAULT)) {
1491 					goto check_fetch_type;
1492 				}
1493 			}
1494 			break;
1495 	}
1496 
1497 	if (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) {
1498 		return zend_lookup_class_ex(class_name, NULL, fetch_type);
1499 	} else if ((ce = zend_lookup_class_ex(class_name, NULL, fetch_type)) == NULL) {
1500 		if (!(fetch_type & ZEND_FETCH_CLASS_SILENT) && !EG(exception)) {
1501 			if (fetch_sub_type == ZEND_FETCH_CLASS_INTERFACE) {
1502 				zend_throw_or_error(fetch_type, NULL, "Interface \"%s\" not found", ZSTR_VAL(class_name));
1503 			} else if (fetch_sub_type == ZEND_FETCH_CLASS_TRAIT) {
1504 				zend_throw_or_error(fetch_type, NULL, "Trait \"%s\" not found", ZSTR_VAL(class_name));
1505 			} else {
1506 				zend_throw_or_error(fetch_type, NULL, "Class \"%s\" not found", ZSTR_VAL(class_name));
1507 			}
1508 		}
1509 		return NULL;
1510 	}
1511 	return ce;
1512 }
1513 /* }}} */
1514 
zend_fetch_class_by_name(zend_string * class_name,zend_string * key,int fetch_type)1515 zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *key, int fetch_type) /* {{{ */
1516 {
1517 	zend_class_entry *ce;
1518 
1519 	if (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) {
1520 		return zend_lookup_class_ex(class_name, key, fetch_type);
1521 	} else if ((ce = zend_lookup_class_ex(class_name, key, fetch_type)) == NULL) {
1522 		if (fetch_type & ZEND_FETCH_CLASS_SILENT) {
1523 			return NULL;
1524 		}
1525 		if (EG(exception)) {
1526 			if (!(fetch_type & ZEND_FETCH_CLASS_EXCEPTION)) {
1527 				zend_string *exception_str;
1528 				zval exception_zv;
1529 				ZVAL_OBJ(&exception_zv, EG(exception));
1530 				Z_ADDREF(exception_zv);
1531 				zend_clear_exception();
1532 				exception_str = zval_get_string(&exception_zv);
1533 				zend_error_noreturn(E_ERROR,
1534 					"During class fetch: Uncaught %s", ZSTR_VAL(exception_str));
1535 			}
1536 			return NULL;
1537 		}
1538 		if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) {
1539 			zend_throw_or_error(fetch_type, NULL, "Interface \"%s\" not found", ZSTR_VAL(class_name));
1540 		} else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) {
1541 			zend_throw_or_error(fetch_type, NULL, "Trait \"%s\" not found", ZSTR_VAL(class_name));
1542 		} else {
1543 			zend_throw_or_error(fetch_type, NULL, "Class \"%s\" not found", ZSTR_VAL(class_name));
1544 		}
1545 		return NULL;
1546 	}
1547 	return ce;
1548 }
1549 /* }}} */
1550 
zend_delete_global_variable(zend_string * name)1551 ZEND_API zend_result zend_delete_global_variable(zend_string *name) /* {{{ */
1552 {
1553     return zend_hash_del_ind(&EG(symbol_table), name);
1554 }
1555 /* }}} */
1556 
zend_rebuild_symbol_table(void)1557 ZEND_API zend_array *zend_rebuild_symbol_table(void) /* {{{ */
1558 {
1559 	zend_execute_data *ex;
1560 	zend_array *symbol_table;
1561 
1562 	/* Search for last called user function */
1563 	ex = EG(current_execute_data);
1564 	while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) {
1565 		ex = ex->prev_execute_data;
1566 	}
1567 	if (!ex) {
1568 		return NULL;
1569 	}
1570 	if (ZEND_CALL_INFO(ex) & ZEND_CALL_HAS_SYMBOL_TABLE) {
1571 		return ex->symbol_table;
1572 	}
1573 
1574 	ZEND_ADD_CALL_FLAG(ex, ZEND_CALL_HAS_SYMBOL_TABLE);
1575 	if (EG(symtable_cache_ptr) > EG(symtable_cache)) {
1576 		symbol_table = ex->symbol_table = *(--EG(symtable_cache_ptr));
1577 		if (!ex->func->op_array.last_var) {
1578 			return symbol_table;
1579 		}
1580 		zend_hash_extend(symbol_table, ex->func->op_array.last_var, 0);
1581 	} else {
1582 		symbol_table = ex->symbol_table = zend_new_array(ex->func->op_array.last_var);
1583 		if (!ex->func->op_array.last_var) {
1584 			return symbol_table;
1585 		}
1586 		zend_hash_real_init_mixed(symbol_table);
1587 		/*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
1588 	}
1589 	if (EXPECTED(ex->func->op_array.last_var)) {
1590 		zend_string **str = ex->func->op_array.vars;
1591 		zend_string **end = str + ex->func->op_array.last_var;
1592 		zval *var = ZEND_CALL_VAR_NUM(ex, 0);
1593 
1594 		do {
1595 			_zend_hash_append_ind(symbol_table, *str, var);
1596 			str++;
1597 			var++;
1598 		} while (str != end);
1599 	}
1600 	return symbol_table;
1601 }
1602 /* }}} */
1603 
zend_attach_symbol_table(zend_execute_data * execute_data)1604 ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ */
1605 {
1606 	zend_op_array *op_array = &execute_data->func->op_array;
1607 	HashTable *ht = execute_data->symbol_table;
1608 
1609 	/* copy real values from symbol table into CV slots and create
1610 	   INDIRECT references to CV in symbol table  */
1611 	if (EXPECTED(op_array->last_var)) {
1612 		zend_string **str = op_array->vars;
1613 		zend_string **end = str + op_array->last_var;
1614 		zval *var = EX_VAR_NUM(0);
1615 
1616 		do {
1617 			zval *zv = zend_hash_find_ex(ht, *str, 1);
1618 
1619 			if (zv) {
1620 				if (Z_TYPE_P(zv) == IS_INDIRECT) {
1621 					zval *val = Z_INDIRECT_P(zv);
1622 
1623 					ZVAL_COPY_VALUE(var, val);
1624 				} else {
1625 					ZVAL_COPY_VALUE(var, zv);
1626 				}
1627 			} else {
1628 				ZVAL_UNDEF(var);
1629 				zv = zend_hash_add_new(ht, *str, var);
1630 			}
1631 			ZVAL_INDIRECT(zv, var);
1632 			str++;
1633 			var++;
1634 		} while (str != end);
1635 	}
1636 }
1637 /* }}} */
1638 
zend_detach_symbol_table(zend_execute_data * execute_data)1639 ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ */
1640 {
1641 	zend_op_array *op_array = &execute_data->func->op_array;
1642 	HashTable *ht = execute_data->symbol_table;
1643 
1644 	/* copy real values from CV slots into symbol table */
1645 	if (EXPECTED(op_array->last_var)) {
1646 		zend_string **str = op_array->vars;
1647 		zend_string **end = str + op_array->last_var;
1648 		zval *var = EX_VAR_NUM(0);
1649 
1650 		do {
1651 			if (Z_TYPE_P(var) == IS_UNDEF) {
1652 				zend_hash_del(ht, *str);
1653 			} else {
1654 				zend_hash_update(ht, *str, var);
1655 				ZVAL_UNDEF(var);
1656 			}
1657 			str++;
1658 			var++;
1659 		} while (str != end);
1660 	}
1661 }
1662 /* }}} */
1663 
zend_set_local_var(zend_string * name,zval * value,bool force)1664 ZEND_API zend_result zend_set_local_var(zend_string *name, zval *value, bool force) /* {{{ */
1665 {
1666 	zend_execute_data *execute_data = EG(current_execute_data);
1667 
1668 	while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
1669 		execute_data = execute_data->prev_execute_data;
1670 	}
1671 
1672 	if (execute_data) {
1673 		if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) {
1674 			zend_ulong h = zend_string_hash_val(name);
1675 			zend_op_array *op_array = &execute_data->func->op_array;
1676 
1677 			if (EXPECTED(op_array->last_var)) {
1678 				zend_string **str = op_array->vars;
1679 				zend_string **end = str + op_array->last_var;
1680 
1681 				do {
1682 					if (ZSTR_H(*str) == h &&
1683 					    zend_string_equal_content(*str, name)) {
1684 						zval *var = EX_VAR_NUM(str - op_array->vars);
1685 						ZVAL_COPY_VALUE(var, value);
1686 						return SUCCESS;
1687 					}
1688 					str++;
1689 				} while (str != end);
1690 			}
1691 			if (force) {
1692 				zend_array *symbol_table = zend_rebuild_symbol_table();
1693 				if (symbol_table) {
1694 					zend_hash_update(symbol_table, name, value);
1695 					return SUCCESS;
1696 				}
1697 			}
1698 		} else {
1699 			zend_hash_update_ind(execute_data->symbol_table, name, value);
1700 			return SUCCESS;
1701 		}
1702 	}
1703 	return FAILURE;
1704 }
1705 /* }}} */
1706 
zend_set_local_var_str(const char * name,size_t len,zval * value,bool force)1707 ZEND_API zend_result zend_set_local_var_str(const char *name, size_t len, zval *value, bool force) /* {{{ */
1708 {
1709 	zend_execute_data *execute_data = EG(current_execute_data);
1710 
1711 	while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
1712 		execute_data = execute_data->prev_execute_data;
1713 	}
1714 
1715 	if (execute_data) {
1716 		if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) {
1717 			zend_ulong h = zend_hash_func(name, len);
1718 			zend_op_array *op_array = &execute_data->func->op_array;
1719 			if (EXPECTED(op_array->last_var)) {
1720 				zend_string **str = op_array->vars;
1721 				zend_string **end = str + op_array->last_var;
1722 
1723 				do {
1724 					if (ZSTR_H(*str) == h &&
1725 					    ZSTR_LEN(*str) == len &&
1726 					    memcmp(ZSTR_VAL(*str), name, len) == 0) {
1727 						zval *var = EX_VAR_NUM(str - op_array->vars);
1728 						zval_ptr_dtor(var);
1729 						ZVAL_COPY_VALUE(var, value);
1730 						return SUCCESS;
1731 					}
1732 					str++;
1733 				} while (str != end);
1734 			}
1735 			if (force) {
1736 				zend_array *symbol_table = zend_rebuild_symbol_table();
1737 				if (symbol_table) {
1738 					zend_hash_str_update(symbol_table, name, len, value);
1739 					return SUCCESS;
1740 				}
1741 			}
1742 		} else {
1743 			zend_hash_str_update_ind(execute_data->symbol_table, name, len, value);
1744 			return SUCCESS;
1745 		}
1746 	}
1747 	return FAILURE;
1748 }
1749 /* }}} */
1750