1 : /*
2 : +----------------------------------------------------------------------+
3 : | Zend Engine |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1998-2009 Zend Technologies Ltd. (http://www.zend.com) |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 2.00 of the Zend license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.zend.com/license/2_00.txt. |
11 : | If you did not receive a copy of the Zend license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@zend.com so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Authors: Andi Gutmans <andi@zend.com> |
16 : | Zeev Suraski <zeev@zend.com> |
17 : +----------------------------------------------------------------------+
18 : */
19 :
20 : /* $Id: zend_execute_API.c 290231 2009-11-05 09:33:19Z dmitry $ */
21 :
22 : #include <stdio.h>
23 : #include <signal.h>
24 :
25 : #include "zend.h"
26 : #include "zend_compile.h"
27 : #include "zend_execute.h"
28 : #include "zend_API.h"
29 : #include "zend_ptr_stack.h"
30 : #include "zend_constants.h"
31 : #include "zend_extensions.h"
32 : #include "zend_closures.h"
33 : #include "zend_exceptions.h"
34 : #include "zend_vm.h"
35 : #include "zend_float.h"
36 : #ifdef HAVE_SYS_TIME_H
37 : #include <sys/time.h>
38 : #endif
39 :
40 : ZEND_API void (*zend_execute)(zend_op_array *op_array TSRMLS_DC);
41 : ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
42 :
43 : /* true globals */
44 : ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 };
45 : ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL };
46 :
47 : #ifdef ZEND_WIN32
48 : #include <process.h>
49 : static WNDCLASS wc;
50 : static HWND timeout_window;
51 : static HANDLE timeout_thread_event;
52 : static HANDLE timeout_thread_handle;
53 : static DWORD timeout_thread_id;
54 : static int timeout_thread_initialized=0;
55 : #endif
56 :
57 : UChar u_main[sizeof("main")];
58 : UChar u_return[sizeof("return ")];
59 : UChar u_doublecolon[sizeof("::")];
60 :
61 : void init_unicode_strings(void)
62 16993 : {
63 16993 : u_charsToUChars("main", u_main, sizeof("main"));
64 16993 : u_charsToUChars("return ", u_return, sizeof("return "));
65 16993 : u_charsToUChars("::", u_doublecolon, sizeof("::"));
66 16993 : }
67 :
68 : #if 0&&ZEND_DEBUG
69 : static void (*original_sigsegv_handler)(int);
70 : static void zend_handle_sigsegv(int dummy) /* {{{ */
71 : {
72 : fflush(stdout);
73 : fflush(stderr);
74 : if (original_sigsegv_handler == zend_handle_sigsegv) {
75 : signal(SIGSEGV, original_sigsegv_handler);
76 : } else {
77 : signal(SIGSEGV, SIG_DFL);
78 : }
79 : {
80 : TSRMLS_FETCH();
81 :
82 : fprintf(stderr, "SIGSEGV caught on opcode %d on opline %d of %s() at %s:%d\n\n",
83 : active_opline->opcode,
84 : active_opline-EG(active_op_array)->opcodes,
85 : get_active_function_name(TSRMLS_C).s,
86 : zend_get_executed_filename(TSRMLS_C),
87 : zend_get_executed_lineno(TSRMLS_C));
88 : }
89 : if (original_sigsegv_handler!=zend_handle_sigsegv) {
90 : original_sigsegv_handler(dummy);
91 : }
92 : }
93 : /* }}} */
94 : #endif
95 :
96 : static void zend_extension_activator(zend_extension *extension TSRMLS_DC) /* {{{ */
97 0 : {
98 0 : if (extension->activate) {
99 0 : extension->activate();
100 : }
101 0 : }
102 : /* }}} */
103 :
104 : static void zend_extension_deactivator(zend_extension *extension TSRMLS_DC) /* {{{ */
105 0 : {
106 0 : if (extension->deactivate) {
107 0 : extension->deactivate();
108 : }
109 0 : }
110 : /* }}} */
111 :
112 : static int clean_non_persistent_function(zend_function *function TSRMLS_DC) /* {{{ */
113 27335 : {
114 27335 : return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
115 : }
116 : /* }}} */
117 :
118 : static int clean_non_persistent_function_full(zend_function *function TSRMLS_DC) /* {{{ */
119 0 : {
120 0 : return (function->type != ZEND_INTERNAL_FUNCTION);
121 : }
122 : /* }}} */
123 :
124 : static int clean_non_persistent_class(zend_class_entry **ce TSRMLS_DC) /* {{{ */
125 24433 : {
126 24433 : return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
127 : }
128 : /* }}} */
129 :
130 : static int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC) /* {{{ */
131 0 : {
132 0 : return ((*ce)->type != ZEND_INTERNAL_CLASS);
133 : }
134 : /* }}} */
135 :
136 : void init_executor(TSRMLS_D) /* {{{ */
137 16993 : {
138 16993 : zend_init_fpu(TSRMLS_C);
139 :
140 16993 : INIT_ZVAL(EG(uninitialized_zval));
141 : /* trick to make uninitialized_zval never be modified, passed by ref, etc. */
142 16993 : Z_ADDREF(EG(uninitialized_zval));
143 16993 : INIT_ZVAL(EG(error_zval));
144 16993 : EG(uninitialized_zval_ptr)=&EG(uninitialized_zval);
145 16993 : EG(error_zval_ptr)=&EG(error_zval);
146 16993 : zend_ptr_stack_init(&EG(arg_types_stack));
147 : /* destroys stack frame, therefore makes core dumps worthless */
148 : #if 0&&ZEND_DEBUG
149 : original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv);
150 : #endif
151 16993 : EG(return_value_ptr_ptr) = NULL;
152 :
153 16993 : EG(symtable_cache_ptr) = EG(symtable_cache) - 1;
154 16993 : EG(symtable_cache_limit) = EG(symtable_cache) + SYMTABLE_CACHE_SIZE - 1;
155 16993 : EG(no_extensions) = 0;
156 :
157 16993 : EG(function_table) = CG(function_table);
158 16993 : EG(class_table) = CG(class_table);
159 :
160 16993 : EG(in_execution) = 0;
161 16993 : EG(in_autoload) = NULL;
162 16993 : EG(autoload_func) = NULL;
163 16993 : EG(error_handling) = EH_NORMAL;
164 :
165 16993 : zend_vm_stack_init(TSRMLS_C);
166 16993 : zend_vm_stack_push((void *) NULL TSRMLS_CC);
167 :
168 16993 : zend_u_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
169 : {
170 : zval *globals;
171 :
172 16993 : ALLOC_ZVAL(globals);
173 16993 : Z_SET_REFCOUNT_P(globals, 1);
174 16993 : Z_SET_ISREF_P(globals);
175 16993 : Z_TYPE_P(globals) = IS_ARRAY;
176 16993 : Z_ARRVAL_P(globals) = &EG(symbol_table);
177 16993 : zend_ascii_hash_update(&EG(symbol_table), "GLOBALS", sizeof("GLOBALS"), &globals, sizeof(zval *), NULL);
178 : }
179 16993 : EG(active_symbol_table) = &EG(symbol_table);
180 :
181 16993 : zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC);
182 16993 : EG(opline_ptr) = NULL;
183 :
184 16993 : zend_hash_init(&EG(included_files), 5, NULL, NULL, 0);
185 :
186 16993 : EG(ticks_count) = 0;
187 :
188 16993 : EG(user_error_handler) = NULL;
189 :
190 16993 : EG(current_execute_data) = NULL;
191 :
192 16993 : zend_stack_init(&EG(user_error_handlers_error_reporting));
193 16993 : zend_ptr_stack_init(&EG(user_error_handlers));
194 16993 : zend_ptr_stack_init(&EG(user_exception_handlers));
195 16993 : zend_ptr_stack_init(&UG(conv_error_handlers));
196 :
197 16993 : zend_objects_store_init(&EG(objects_store), 1024);
198 :
199 16993 : EG(full_tables_cleanup) = 0;
200 : #ifdef ZEND_WIN32
201 : EG(timed_out) = 0;
202 : #endif
203 :
204 16993 : EG(exception) = NULL;
205 16993 : EG(prev_exception) = NULL;
206 :
207 16993 : EG(scope) = NULL;
208 16993 : EG(called_scope) = NULL;
209 :
210 16993 : EG(This) = NULL;
211 :
212 16993 : EG(active_op_array) = NULL;
213 :
214 16993 : EG(active) = 1;
215 16993 : }
216 : /* }}} */
217 :
218 : static int zval_call_destructor(zval **zv TSRMLS_DC) /* {{{ */
219 246882 : {
220 246882 : if (Z_TYPE_PP(zv) == IS_OBJECT && Z_REFCOUNT_PP(zv) == 1) {
221 6927 : return ZEND_HASH_APPLY_REMOVE;
222 : } else {
223 239955 : return ZEND_HASH_APPLY_KEEP;
224 : }
225 : }
226 : /* }}} */
227 :
228 : void shutdown_destructors(TSRMLS_D) /* {{{ */
229 17025 : {
230 17025 : zend_try {
231 : int symbols;
232 : do {
233 20964 : symbols = zend_hash_num_elements(&EG(symbol_table));
234 20964 : zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor TSRMLS_CC);
235 20964 : } while (symbols != zend_hash_num_elements(&EG(symbol_table)));
236 17025 : zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC);
237 0 : } zend_catch {
238 : /* if we couldn't destruct cleanly, mark all objects as destructed anyway */
239 0 : zend_objects_store_mark_destructed(&EG(objects_store) TSRMLS_CC);
240 17025 : } zend_end_try();
241 17025 : }
242 : /* }}} */
243 :
244 : void shutdown_executor(TSRMLS_D) /* {{{ */
245 17025 : {
246 17025 : zend_try {
247 : /* Removed because this can not be safely done, e.g. in this situation:
248 : Object 1 creates object 2
249 : Object 3 holds reference to object 2.
250 : Now when 1 and 2 are destroyed, 3 can still access 2 in its destructor, with
251 : very problematic results */
252 : /* zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC); */
253 :
254 : /* Moved after symbol table cleaners, because some of the cleaners can call
255 : destructors, which would use EG(symtable_cache_ptr) and thus leave leaks */
256 : /* while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
257 : zend_hash_destroy(*EG(symtable_cache_ptr));
258 : efree(*EG(symtable_cache_ptr));
259 : EG(symtable_cache_ptr)--;
260 : }
261 : */
262 17025 : zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator TSRMLS_CC);
263 17025 : zend_hash_graceful_reverse_destroy(&EG(symbol_table));
264 17025 : } zend_end_try();
265 :
266 17025 : zend_try {
267 : zval *zeh;
268 : /* remove error handlers before destroying classes and functions,
269 : * so that if handler used some class, crash would not happen */
270 17025 : if (EG(user_error_handler)) {
271 216 : zeh = EG(user_error_handler);
272 216 : EG(user_error_handler) = NULL;
273 216 : zval_dtor(zeh);
274 216 : FREE_ZVAL(zeh);
275 : }
276 :
277 17025 : if (EG(user_exception_handler)) {
278 10 : zeh = EG(user_exception_handler);
279 10 : EG(user_exception_handler) = NULL;
280 10 : zval_dtor(zeh);
281 10 : FREE_ZVAL(zeh);
282 : }
283 :
284 17025 : if (UG(conv_error_handler)) {
285 0 : zeh = UG(conv_error_handler);
286 0 : UG(conv_error_handler) = NULL;
287 0 : zval_dtor(zeh);
288 0 : FREE_ZVAL(zeh);
289 : }
290 :
291 17025 : zend_stack_destroy(&EG(user_error_handlers_error_reporting));
292 17025 : zend_stack_init(&EG(user_error_handlers_error_reporting));
293 17025 : zend_ptr_stack_clean(&EG(user_error_handlers), ZVAL_DESTRUCTOR, 1);
294 17025 : zend_ptr_stack_clean(&EG(user_exception_handlers), ZVAL_DESTRUCTOR, 1);
295 17025 : zend_ptr_stack_clean(&UG(conv_error_handlers), ZVAL_DESTRUCTOR, 1);
296 17025 : } zend_end_try();
297 :
298 17025 : zend_try {
299 : /* Cleanup static data for functions and arrays.
300 : * We need a separate cleanup stage because of the following problem:
301 : * Suppose we destroy class X, which destroys the class's function table,
302 : * and in the function table we have function foo() that has static $bar.
303 : * Now if an object of class X is assigned to $bar, its destructor will be
304 : * called and will fail since X's function table is in mid-destruction.
305 : * So we want first of all to clean up all data and then move to tables destruction.
306 : * Note that only run-time accessed data need to be cleaned up, pre-defined data can
307 : * not contain objects and thus are not probelmatic */
308 17025 : if (EG(full_tables_cleanup)) {
309 0 : zend_hash_apply(EG(function_table), (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC);
310 : } else {
311 17025 : zend_hash_reverse_apply(EG(function_table), (apply_func_t) zend_cleanup_function_data TSRMLS_CC);
312 : }
313 17025 : zend_hash_apply(EG(class_table), (apply_func_t) zend_cleanup_class_data TSRMLS_CC);
314 :
315 17025 : zend_vm_stack_destroy(TSRMLS_C);
316 :
317 17025 : zend_objects_store_free_object_storage(&EG(objects_store) TSRMLS_CC);
318 :
319 : /* Destroy all op arrays */
320 17025 : if (EG(full_tables_cleanup)) {
321 0 : zend_hash_apply(EG(function_table), (apply_func_t) clean_non_persistent_function_full TSRMLS_CC);
322 0 : zend_hash_apply(EG(class_table), (apply_func_t) clean_non_persistent_class_full TSRMLS_CC);
323 : } else {
324 17025 : zend_hash_reverse_apply(EG(function_table), (apply_func_t) clean_non_persistent_function TSRMLS_CC);
325 17025 : zend_hash_reverse_apply(EG(class_table), (apply_func_t) clean_non_persistent_class TSRMLS_CC);
326 : }
327 :
328 34526 : while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
329 476 : zend_hash_destroy(*EG(symtable_cache_ptr));
330 476 : FREE_HASHTABLE(*EG(symtable_cache_ptr));
331 476 : EG(symtable_cache_ptr)--;
332 : }
333 17025 : } zend_end_try();
334 :
335 17025 : zend_try {
336 17025 : clean_non_persistent_constants(TSRMLS_C);
337 17025 : } zend_end_try();
338 :
339 17025 : zend_try {
340 : #if 0&&ZEND_DEBUG
341 : signal(SIGSEGV, original_sigsegv_handler);
342 : #endif
343 :
344 17025 : zend_hash_destroy(&EG(included_files));
345 :
346 17025 : zend_ptr_stack_destroy(&EG(arg_types_stack));
347 17025 : zend_stack_destroy(&EG(user_error_handlers_error_reporting));
348 17025 : zend_ptr_stack_destroy(&EG(user_error_handlers));
349 17025 : zend_ptr_stack_destroy(&EG(user_exception_handlers));
350 17025 : zend_ptr_stack_destroy(&UG(conv_error_handlers));
351 17025 : zend_objects_store_destroy(&EG(objects_store));
352 17025 : if (EG(in_autoload)) {
353 138 : zend_hash_destroy(EG(in_autoload));
354 138 : FREE_HASHTABLE(EG(in_autoload));
355 : }
356 17025 : } zend_end_try();
357 :
358 17025 : zend_shutdown_fpu(TSRMLS_C);
359 :
360 17025 : EG(active) = 0;
361 17025 : }
362 : /* }}} */
363 :
364 : /* return class name and "::" or "". */
365 : ZEND_API zstr get_active_class_name(char **space TSRMLS_DC) /* {{{ */
366 2623723 : {
367 2623723 : if (!zend_is_executing(TSRMLS_C)) {
368 0 : if (space) {
369 0 : *space = "";
370 : }
371 0 : return EMPTY_ZSTR;
372 : }
373 2623723 : switch (EG(current_execute_data)->function_state.function->type) {
374 : case ZEND_USER_FUNCTION:
375 : case ZEND_INTERNAL_FUNCTION:
376 : {
377 2623723 : zend_class_entry *ce = EG(current_execute_data)->function_state.function->common.scope;
378 :
379 2623723 : if (space) {
380 2623723 : *space = ce ? "::" : "";
381 : }
382 2623723 : return ce ? ce->name : EMPTY_ZSTR;
383 : }
384 : default:
385 0 : if (space) {
386 0 : *space = "";
387 : }
388 0 : return EMPTY_ZSTR;
389 : }
390 : }
391 : /* }}} */
392 :
393 : ZEND_API zstr get_active_function_name(TSRMLS_D) /* {{{ */
394 2623731 : {
395 : zstr ret;
396 :
397 2623731 : if (!zend_is_executing(TSRMLS_C)) {
398 7 : return NULL_ZSTR;
399 : }
400 2623724 : switch (EG(current_execute_data)->function_state.function->type) {
401 : case ZEND_USER_FUNCTION: {
402 122 : zstr function_name = ((zend_op_array *)EG(current_execute_data)->function_state.function)->function_name;
403 :
404 122 : if (function_name.v) {
405 66 : return function_name;
406 : } else {
407 56 : ret.u = u_main;
408 : }
409 56 : return ret;
410 : }
411 : break;
412 : case ZEND_INTERNAL_FUNCTION:
413 2623602 : return ((zend_internal_function *)EG(current_execute_data)->function_state.function)->function_name;
414 : break;
415 : default:
416 0 : return NULL_ZSTR;
417 : }
418 : }
419 : /* }}} */
420 :
421 : ZEND_API char *zend_get_executed_filename(TSRMLS_D) /* {{{ */
422 2745797 : {
423 2745797 : if (EG(active_op_array)) {
424 2745792 : return EG(active_op_array)->filename;
425 : } else {
426 5 : return "[no active file]";
427 : }
428 : }
429 : /* }}} */
430 :
431 : ZEND_API uint zend_get_executed_lineno(TSRMLS_D) /* {{{ */
432 2739845 : {
433 2739845 : if (EG(opline_ptr)) {
434 2739840 : return active_opline->lineno;
435 : } else {
436 5 : return 0;
437 : }
438 : }
439 : /* }}} */
440 :
441 : ZEND_API zend_bool zend_is_executing(TSRMLS_D) /* {{{ */
442 8038751 : {
443 8038751 : return EG(in_execution);
444 : }
445 : /* }}} */
446 :
447 : ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */
448 256208669 : {
449 : #if DEBUG_ZEND>=2
450 : printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, Z_REFCOUNT_PP(zval_ptr), Z_REFCOUNT_PP(zval_ptr) - 1);
451 : #endif
452 256208669 : Z_DELREF_PP(zval_ptr);
453 256208669 : if (Z_REFCOUNT_PP(zval_ptr) == 0) {
454 : TSRMLS_FETCH();
455 :
456 69437486 : if (*zval_ptr != &EG(uninitialized_zval)) {
457 69437486 : GC_REMOVE_ZVAL_FROM_BUFFER(*zval_ptr);
458 69437486 : zval_dtor(*zval_ptr);
459 69437485 : efree_rel(*zval_ptr);
460 : }
461 : } else {
462 : TSRMLS_FETCH();
463 :
464 186771183 : if (Z_REFCOUNT_PP(zval_ptr) == 1) {
465 58882864 : Z_UNSET_ISREF_PP(zval_ptr);
466 : }
467 186771183 : GC_ZVAL_CHECK_POSSIBLE_ROOT(*zval_ptr);
468 : }
469 256208668 : }
470 : /* }}} */
471 :
472 : ZEND_API void _zval_internal_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */
473 17839705 : {
474 : #if DEBUG_ZEND>=2
475 : printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, Z_REFCOUNT_PP(zval_ptr), Z_REFCOUNT_PP(zval_ptr) - 1);
476 : #endif
477 17839705 : Z_DELREF_PP(zval_ptr);
478 17839705 : if (Z_REFCOUNT_PP(zval_ptr) == 0) {
479 13869746 : zval_internal_dtor(*zval_ptr);
480 13869746 : free(*zval_ptr);
481 3969959 : } else if (Z_REFCOUNT_PP(zval_ptr) == 1) {
482 834847 : Z_UNSET_ISREF_PP(zval_ptr);
483 : }
484 17839705 : }
485 : /* }}} */
486 :
487 : ZEND_API int zend_is_true(zval *op) /* {{{ */
488 12504 : {
489 12504 : return i_zend_is_true(op);
490 : }
491 : /* }}} */
492 :
493 : #include "../TSRM/tsrm_strtok_r.h"
494 :
495 : #define IS_VISITED_CONSTANT IS_CONSTANT_INDEX
496 : #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT)
497 : #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT)
498 : #define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT
499 :
500 : static void zval_deep_copy(zval **p)
501 29 : {
502 : zval *value;
503 :
504 29 : ALLOC_ZVAL(value);
505 29 : *value = **p;
506 29 : Z_TYPE_P(value) &= ~IS_CONSTANT_INDEX;
507 29 : zval_copy_ctor(value);
508 29 : Z_TYPE_P(value) = Z_TYPE_PP(p);
509 29 : INIT_PZVAL(value);
510 29 : *p = value;
511 29 : }
512 :
513 : ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */
514 130811 : {
515 130811 : zval *p = *pp;
516 130811 : zend_bool inline_change = (zend_bool) (zend_uintptr_t) arg;
517 : zval const_value;
518 : zstr colon;
519 :
520 130811 : if (IS_CONSTANT_VISITED(p)) {
521 1 : zend_error(E_ERROR, "Cannot declare self-referencing constant '%v'", Z_UNIVAL_P(p));
522 130810 : } else if ((Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
523 : int refcount;
524 : zend_uchar is_ref;
525 :
526 170 : SEPARATE_ZVAL_IF_NOT_REF(pp);
527 170 : p = *pp;
528 :
529 170 : MARK_CONSTANT_VISITED(p);
530 :
531 170 : refcount = Z_REFCOUNT_P(p);
532 170 : is_ref = Z_ISREF_P(p);
533 :
534 170 : if (!zend_u_get_constant_ex(IS_UNICODE, Z_UNIVAL_P(p), Z_UNILEN_P(p), &const_value, scope, Z_REAL_TYPE_P(p) TSRMLS_CC)) {
535 13 : zstr actual = Z_UNIVAL_P(p);
536 13 : if ((colon.u = u_memrchr(Z_USTRVAL_P(p), ':', Z_USTRLEN_P(p))) && colon.u > Z_USTRVAL_P(p) && *(colon.u - 1) == ':') {
537 0 : zend_error(E_ERROR, "Undefined class constant '%v'", actual);
538 : } else {
539 13 : zstr save = actual, slash;
540 13 : int actual_len = Z_UNILEN_P(p);
541 : if(IS_UNICODE == IS_UNICODE) {
542 13 : slash.u = u_memrchr(actual.u, '\\', actual_len);
543 : } else {
544 : slash.s = zend_memrchr(actual.s, '\\', actual_len);
545 : }
546 13 : if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) && slash.v != NULL) {
547 : if(IS_UNICODE == IS_UNICODE) {
548 2 : actual.u = slash.u + 1;
549 2 : actual_len -= (actual.u - Z_USTRVAL_P(p));
550 : } else {
551 : actual.s = slash.s + 1;
552 : actual_len -= (actual.s - Z_STRVAL_P(p));
553 : }
554 :
555 2 : if (inline_change) {
556 1 : int type = Z_TYPE_P(p);
557 1 : ZVAL_ZSTRL(p, IS_UNICODE, actual, actual_len, 1);
558 1 : Z_TYPE_P(p) = type;
559 1 : actual = Z_UNIVAL_P(p);
560 : }
561 : }
562 13 : if(IS_UNICODE == IS_UNICODE && actual.u[0] == '\\') {
563 0 : if (inline_change) {
564 0 : memmove(Z_USTRVAL_P(p), Z_USTRVAL_P(p)+1, UBYTES(Z_USTRLEN_P(p)));
565 0 : --Z_USTRLEN_P(p);
566 : } else {
567 0 : ++actual.u;
568 : }
569 0 : --actual_len;
570 : } else if(IS_UNICODE == IS_STRING && actual.s[0] == '\\') {
571 : if (inline_change) {
572 : memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p));
573 : --Z_STRLEN_P(p);
574 : } else {
575 : ++actual.s;
576 : }
577 : --actual_len;
578 : }
579 13 : if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) {
580 10 : int fix_save = 0;
581 10 : if (IS_UNICODE == IS_UNICODE && save.u[0] == '\\') {
582 0 : save.u++;
583 0 : fix_save = 1;
584 : } else if (IS_UNICODE == IS_STRING && save.s[0] == '\\') {
585 : save.s++;
586 : fix_save = 1;
587 : }
588 10 : zend_error(E_ERROR, "Undefined constant '%v'", save);
589 0 : if (fix_save) {
590 0 : --save.u;
591 : }
592 0 : if (inline_change) {
593 0 : efree(save.v);
594 : }
595 0 : save.v = NULL;
596 : }
597 3 : if (inline_change && save.v && save.v != actual.v) {
598 1 : efree(save.v);
599 : }
600 3 : zend_error(E_NOTICE, "Use of undefined constant %v - assumed '%v'", actual, actual);
601 3 : Z_TYPE_P(p) = IS_UNICODE;
602 3 : if (!inline_change) {
603 1 : ZVAL_ZSTRL(p, Z_TYPE_P(p), actual, actual_len, 0);
604 1 : zval_copy_ctor(p);
605 : }
606 : }
607 : } else {
608 149 : if (inline_change) {
609 95 : STR_FREE(Z_STRVAL_P(p));
610 : }
611 149 : *p = const_value;
612 : }
613 :
614 152 : Z_SET_REFCOUNT_P(p, refcount);
615 152 : Z_SET_ISREF_TO_P(p, is_ref);
616 130640 : } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) {
617 : zval **element, *new_val;
618 : zstr str_index;
619 : uint str_index_len;
620 : ulong num_index;
621 : int ret;
622 :
623 862 : SEPARATE_ZVAL_IF_NOT_REF(pp);
624 862 : p = *pp;
625 862 : Z_TYPE_P(p) = IS_ARRAY;
626 :
627 862 : if (!inline_change) {
628 : zval *tmp;
629 45 : HashTable *tmp_ht = NULL;
630 :
631 45 : ALLOC_HASHTABLE(tmp_ht);
632 45 : zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0);
633 45 : zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *));
634 45 : Z_ARRVAL_P(p) = tmp_ht;
635 : }
636 :
637 : /* First go over the array and see if there are any constant indices */
638 862 : zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
639 3937 : while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element) == SUCCESS) {
640 2219 : if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) {
641 2138 : zend_hash_move_forward(Z_ARRVAL_P(p));
642 2138 : continue;
643 : }
644 81 : Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX;
645 81 : if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL) != HASH_KEY_IS_UNICODE) {
646 0 : zend_hash_move_forward(Z_ARRVAL_P(p));
647 0 : continue;
648 : }
649 81 : if (!zend_u_get_constant_ex(IS_UNICODE, str_index, str_index_len - 3, &const_value, scope, str_index.u[str_index_len-2] TSRMLS_CC)) {
650 7 : UChar *actual, *save = str_index.u;
651 7 : if ((colon.u = u_memrchr(str_index.u, ':', str_index_len - 3)) && colon.u > str_index.u && *(colon.u-1) == ':') {
652 0 : zend_error(E_ERROR, "Undefined class constant '%v'", str_index);
653 0 : str_index_len -= ((colon.u - str_index.u) + 1);
654 0 : str_index.u = colon.u + 1;
655 : } else {
656 7 : if (str_index.u[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) {
657 2 : if ((actual = (UChar *)u_memrchr(str_index.u, '\\', str_index_len - 3))) {
658 1 : actual++;
659 1 : str_index_len -= (actual - str_index.u);
660 1 : str_index.u = actual;
661 : }
662 : }
663 7 : if (str_index.u[0] == '\\') {
664 0 : ++str_index.u;
665 0 : --str_index_len;
666 : }
667 7 : if (save[0] == '\\') {
668 0 : ++save;
669 : }
670 7 : if ((str_index.u[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) {
671 5 : zend_error(E_ERROR, "Undefined constant '%r'", save);
672 : }
673 : }
674 2 : zend_error(E_NOTICE, "Use of undefined constant %v - assumed '%v'", str_index, str_index);
675 2 : ZVAL_UNICODEL(&const_value, str_index.u, str_index_len-3, 1);
676 : }
677 :
678 75 : if (Z_REFCOUNT_PP(element) > 1) {
679 3 : ALLOC_ZVAL(new_val);
680 3 : *new_val = **element;
681 3 : zval_copy_ctor(new_val);
682 3 : Z_SET_REFCOUNT_P(new_val, 1);
683 3 : Z_UNSET_ISREF_P(new_val);
684 :
685 : /* preserve this bit for inheritance */
686 3 : Z_TYPE_PP(element) |= IS_CONSTANT_INDEX;
687 3 : zval_ptr_dtor(element);
688 3 : *element = new_val;
689 : }
690 :
691 75 : switch (Z_TYPE(const_value)) {
692 : case IS_STRING:
693 : case IS_UNICODE:
694 27 : ret = zend_u_symtable_update_current_key(Z_ARRVAL_P(p), Z_TYPE(const_value), Z_UNIVAL(const_value), Z_UNILEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE);
695 27 : break;
696 : case IS_BOOL:
697 : case IS_LONG:
698 48 : ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL_ZSTR, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL);
699 48 : break;
700 : case IS_DOUBLE:
701 0 : ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL_ZSTR, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL);
702 0 : break;
703 : case IS_NULL:
704 0 : ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, EMPTY_ZSTR, 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL);
705 0 : break;
706 : default:
707 0 : ret = SUCCESS;
708 : break;
709 : }
710 75 : if (ret == SUCCESS) {
711 71 : zend_hash_move_forward(Z_ARRVAL_P(p));
712 : }
713 75 : zval_dtor(&const_value);
714 : }
715 856 : zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
716 847 : zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
717 : }
718 130777 : return 0;
719 : }
720 : /* }}} */
721 :
722 : ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) /* {{{ */
723 130513 : {
724 130513 : return zval_update_constant_ex(pp, arg, NULL TSRMLS_CC);
725 : }
726 : /* }}} */
727 :
728 : int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC) /* {{{ */
729 983 : {
730 : zval ***params_array;
731 : zend_uint i;
732 : int ex_retval;
733 983 : zval *local_retval_ptr = NULL;
734 :
735 983 : if (param_count) {
736 880 : params_array = (zval ***) emalloc(sizeof(zval **)*param_count);
737 3480 : for (i=0; i<param_count; i++) {
738 2600 : params_array[i] = ¶ms[i];
739 : }
740 : } else {
741 103 : params_array = NULL;
742 : }
743 983 : ex_retval = call_user_function_ex(function_table, object_pp, function_name, &local_retval_ptr, param_count, params_array, 1, NULL TSRMLS_CC);
744 967 : if (local_retval_ptr) {
745 953 : COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr);
746 : } else {
747 14 : INIT_ZVAL(*retval_ptr);
748 : }
749 967 : if (params_array) {
750 867 : efree(params_array);
751 : }
752 967 : return ex_retval;
753 : }
754 : /* }}} */
755 :
756 : int call_user_function_ex(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, zend_uint param_count, zval **params[], int no_separation, HashTable *symbol_table TSRMLS_DC) /* {{{ */
757 10529 : {
758 : zend_fcall_info fci;
759 :
760 10529 : fci.size = sizeof(fci);
761 10529 : fci.function_table = function_table;
762 10529 : fci.object_ptr = object_pp ? *object_pp : NULL;
763 10529 : fci.function_name = function_name;
764 10529 : fci.retval_ptr_ptr = retval_ptr_ptr;
765 10529 : fci.param_count = param_count;
766 10529 : fci.params = params;
767 10529 : fci.no_separation = (zend_bool) no_separation;
768 10529 : fci.symbol_table = symbol_table;
769 :
770 10529 : return zend_call_function(&fci, NULL TSRMLS_CC);
771 : }
772 : /* }}} */
773 :
774 : int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC) /* {{{ */
775 420114 : {
776 : zend_uint i;
777 : zval **original_return_value;
778 : HashTable *calling_symbol_table;
779 : zend_op_array *original_op_array;
780 : zend_op **original_opline_ptr;
781 : zend_class_entry *current_scope;
782 : zend_class_entry *current_called_scope;
783 420114 : zend_class_entry *calling_scope = NULL;
784 420114 : zend_class_entry *called_scope = NULL;
785 : zval *current_this;
786 : zend_execute_data execute_data;
787 420114 : char *old_func_name = NULL;
788 :
789 420114 : *fci->retval_ptr_ptr = NULL;
790 :
791 420114 : if (!EG(active)) {
792 2 : return FAILURE; /* executor is already inactive */
793 : }
794 :
795 420112 : if (EG(exception)) {
796 9 : return FAILURE; /* we would result in an instable executor otherwise */
797 : }
798 :
799 420103 : switch (fci->size) {
800 : case sizeof(zend_fcall_info):
801 420103 : break; /* nothing to do currently */
802 : default:
803 0 : zend_error(E_ERROR, "Corrupted fcall_info provided to zend_call_function()");
804 : break;
805 : }
806 :
807 : /* Initialize execute_data */
808 420103 : if (EG(current_execute_data)) {
809 419603 : execute_data = *EG(current_execute_data);
810 419603 : EX(op_array) = NULL;
811 419603 : EX(opline) = NULL;
812 419603 : EX(object) = NULL;
813 : } else {
814 : /* This only happens when we're called outside any execute()'s
815 : * It shouldn't be strictly necessary to NULL execute_data out,
816 : * but it may make bugs easier to spot
817 : */
818 500 : memset(&execute_data, 0, sizeof(zend_execute_data));
819 : }
820 :
821 420103 : if (!fci_cache || !fci_cache->initialized) {
822 : zend_fcall_info_cache fci_cache_local;
823 : zval callable_name;
824 269289 : char *error = NULL;
825 :
826 269289 : if (!fci_cache) {
827 10786 : fci_cache = &fci_cache_local;
828 : }
829 :
830 269289 : if (!zend_is_callable_ex(fci->function_name, fci->object_ptr, IS_CALLABLE_CHECK_SILENT, &callable_name, fci_cache, &error TSRMLS_CC)) {
831 209 : if (error) {
832 0 : zend_error(E_WARNING, "Invalid callback %Z, %s", callable_name, error);
833 0 : efree(error);
834 : }
835 209 : zval_dtor(&callable_name);
836 209 : return FAILURE;
837 269080 : } else if (error) {
838 : /* Capitalize the first latter of the error message */
839 3 : if (error[0] >= 'a' && error[0] <= 'z') {
840 3 : error[0] += ('A' - 'a');
841 : }
842 3 : zend_error(E_STRICT, "%s", error);
843 3 : efree(error);
844 : }
845 269080 : zval_dtor(&callable_name);
846 : }
847 :
848 419894 : EX(function_state).function = fci_cache->function_handler;
849 419894 : calling_scope = fci_cache->calling_scope;
850 419894 : called_scope = fci_cache->called_scope;
851 419894 : fci->object_ptr = fci_cache->object_ptr;
852 419894 : EX(object) = fci->object_ptr;
853 419894 : if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT
854 : && (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)].valid)) {
855 0 : return FAILURE;
856 : }
857 :
858 419894 : if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
859 1 : if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
860 1 : zend_error_noreturn(E_ERROR, "Cannot call abstract method %v::%v()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
861 : }
862 0 : if (EX(function_state).function->common.fn_flags & ZEND_ACC_DEPRECATED) {
863 0 : zend_error(E_DEPRECATED, "Function %v%s%v() is deprecated",
864 : EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : EMPTY_ZSTR,
865 : EX(function_state).function->common.scope ? "::" : "",
866 : EX(function_state).function->common.function_name);
867 : }
868 : }
869 :
870 419893 : ZEND_VM_STACK_GROW_IF_NEEDED((int)(fci->param_count + 1));
871 :
872 963878 : for (i=0; i<fci->param_count; i++) {
873 : zval *param;
874 :
875 543992 : if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION
876 : && !ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
877 : && PZVAL_IS_REF(*fci->params[i])) {
878 81 : SEPARATE_ZVAL(fci->params[i]);
879 : }
880 :
881 544191 : if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
882 : && !PZVAL_IS_REF(*fci->params[i])) {
883 206 : if (Z_REFCOUNT_PP(fci->params[i]) > 1) {
884 : zval *new_zval;
885 :
886 18 : if (fci->no_separation) {
887 7 : if(i) {
888 : /* hack to clean up the stack */
889 0 : zend_vm_stack_push_nocheck((void *) (zend_uintptr_t)i TSRMLS_CC);
890 0 : zend_vm_stack_clear_multiple(TSRMLS_C);
891 : }
892 7 : if (old_func_name) {
893 0 : efree(Z_STRVAL_P(fci->function_name));
894 0 : Z_TYPE_P(fci->function_name) = IS_STRING;
895 0 : Z_STRVAL_P(fci->function_name) = old_func_name;
896 : }
897 :
898 7 : zend_error(E_WARNING, "Parameter %d to %v%s%v() expected to be a reference, value given",
899 : i+1,
900 : EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : EMPTY_ZSTR,
901 : EX(function_state).function->common.scope ? "::" : "",
902 : EX(function_state).function->common.function_name);
903 7 : return FAILURE;
904 : }
905 11 : ALLOC_ZVAL(new_zval);
906 11 : *new_zval = **fci->params[i];
907 11 : zval_copy_ctor(new_zval);
908 11 : Z_SET_REFCOUNT_P(new_zval, 1);
909 11 : Z_DELREF_PP(fci->params[i]);
910 11 : *fci->params[i] = new_zval;
911 : }
912 199 : Z_ADDREF_PP(fci->params[i]);
913 199 : Z_SET_ISREF_PP(fci->params[i]);
914 199 : param = *fci->params[i];
915 543786 : } else if (*fci->params[i] != &EG(uninitialized_zval)) {
916 543780 : Z_ADDREF_PP(fci->params[i]);
917 543780 : param = *fci->params[i];
918 : } else {
919 6 : ALLOC_ZVAL(param);
920 6 : *param = **(fci->params[i]);
921 6 : INIT_PZVAL(param);
922 : }
923 543985 : zend_vm_stack_push_nocheck(param TSRMLS_CC);
924 : }
925 :
926 419886 : EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
927 419886 : zend_vm_stack_push_nocheck((void*)(zend_uintptr_t)fci->param_count TSRMLS_CC);
928 :
929 419886 : current_scope = EG(scope);
930 419886 : EG(scope) = calling_scope;
931 :
932 419886 : current_this = EG(This);
933 :
934 419886 : current_called_scope = EG(called_scope);
935 419886 : if (called_scope) {
936 158483 : EG(called_scope) = called_scope;
937 261403 : } else if (EX(function_state).function->type != ZEND_INTERNAL_FUNCTION) {
938 260613 : EG(called_scope) = NULL;
939 : }
940 :
941 419886 : if (fci->object_ptr) {
942 158081 : if ((EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) {
943 13 : EG(This) = NULL;
944 : } else {
945 158068 : EG(This) = fci->object_ptr;
946 :
947 158068 : if (!PZVAL_IS_REF(EG(This))) {
948 134212 : Z_ADDREF_P(EG(This)); /* For $this pointer */
949 : } else {
950 : zval *this_ptr;
951 :
952 23856 : ALLOC_ZVAL(this_ptr);
953 23856 : *this_ptr = *EG(This);
954 23856 : INIT_PZVAL(this_ptr);
955 23856 : zval_copy_ctor(this_ptr);
956 23856 : EG(This) = this_ptr;
957 : }
958 : }
959 : } else {
960 261805 : EG(This) = NULL;
961 : }
962 :
963 419886 : EX(prev_execute_data) = EG(current_execute_data);
964 419886 : EG(current_execute_data) = &execute_data;
965 :
966 419886 : if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
967 383761 : calling_symbol_table = EG(active_symbol_table);
968 383761 : EG(scope) = EX(function_state).function->common.scope;
969 383761 : if (fci->symbol_table) {
970 0 : EG(active_symbol_table) = fci->symbol_table;
971 : } else {
972 383761 : EG(active_symbol_table) = NULL;
973 : }
974 :
975 383761 : original_return_value = EG(return_value_ptr_ptr);
976 383761 : original_op_array = EG(active_op_array);
977 383761 : EG(return_value_ptr_ptr) = fci->retval_ptr_ptr;
978 383761 : EG(active_op_array) = (zend_op_array *) EX(function_state).function;
979 383761 : original_opline_ptr = EG(opline_ptr);
980 383761 : zend_execute(EG(active_op_array) TSRMLS_CC);
981 383736 : if (!fci->symbol_table && EG(active_symbol_table)) {
982 180 : if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
983 0 : zend_hash_destroy(EG(active_symbol_table));
984 0 : FREE_HASHTABLE(EG(active_symbol_table));
985 : } else {
986 : /* clean before putting into the cache, since clean
987 : could call dtors, which could use cached hash */
988 180 : zend_hash_clean(EG(active_symbol_table));
989 180 : *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
990 : }
991 : }
992 383736 : EG(active_symbol_table) = calling_symbol_table;
993 383736 : EG(active_op_array) = original_op_array;
994 383736 : EG(return_value_ptr_ptr)=original_return_value;
995 383736 : EG(opline_ptr) = original_opline_ptr;
996 36125 : } else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
997 36125 : int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
998 36125 : ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
999 36125 : if (EX(function_state).function->common.scope) {
1000 35335 : EG(scope) = EX(function_state).function->common.scope;
1001 : }
1002 36125 : ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC);
1003 : /* We shouldn't fix bad extensions here,
1004 : because it can break proper ones (Bug #34045)
1005 : if (!EX(function_state).function->common.return_reference)
1006 : {
1007 : INIT_PZVAL(*fci->retval_ptr_ptr);
1008 : }*/
1009 36115 : if (EG(exception) && fci->retval_ptr_ptr) {
1010 63 : zval_ptr_dtor(fci->retval_ptr_ptr);
1011 63 : *fci->retval_ptr_ptr = NULL;
1012 : }
1013 :
1014 36115 : if (call_via_handler) {
1015 : /* We must re-initialize function again */
1016 32 : fci_cache->initialized = 0;
1017 : }
1018 : } else { /* ZEND_OVERLOADED_FUNCTION */
1019 0 : ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
1020 :
1021 : /* Not sure what should be done here if it's a static method */
1022 0 : if (fci->object_ptr) {
1023 0 : Z_OBJ_HT_P(fci->object_ptr)->call_method(EX(function_state).function->common.function_name, fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC);
1024 : } else {
1025 0 : zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
1026 : }
1027 :
1028 0 : if (EX(function_state).function->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
1029 0 : efree(EX(function_state).function->common.function_name.v);
1030 : }
1031 0 : efree(EX(function_state).function);
1032 :
1033 0 : if (EG(exception) && fci->retval_ptr_ptr) {
1034 0 : zval_ptr_dtor(fci->retval_ptr_ptr);
1035 0 : *fci->retval_ptr_ptr = NULL;
1036 : }
1037 : }
1038 419851 : zend_vm_stack_clear_multiple(TSRMLS_C);
1039 :
1040 419851 : if (EG(This)) {
1041 158050 : zval_ptr_dtor(&EG(This));
1042 : }
1043 419851 : EG(called_scope) = current_called_scope;
1044 419851 : EG(scope) = current_scope;
1045 419851 : EG(This) = current_this;
1046 419851 : EG(current_execute_data) = EX(prev_execute_data);
1047 :
1048 419851 : if (EG(exception)) {
1049 197 : zend_throw_exception_internal(NULL TSRMLS_CC);
1050 : }
1051 419850 : if (old_func_name) {
1052 0 : efree(Z_STRVAL_P(fci->function_name));
1053 0 : Z_TYPE_P(fci->function_name) = IS_STRING;
1054 0 : Z_STRVAL_P(fci->function_name) = old_func_name;
1055 : }
1056 419850 : return SUCCESS;
1057 : }
1058 : /* }}} */
1059 :
1060 : ZEND_API int zend_u_lookup_class_ex(zend_uchar type, zstr name, int name_length, zstr autoload_name, int do_normalize, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
1061 132120 : {
1062 : zval **args[1];
1063 : zval autoload_function;
1064 : zval *class_name_ptr;
1065 132120 : zval *retval_ptr = NULL;
1066 : int retval;
1067 : unsigned int lc_name_len;
1068 : zstr lc_name, lc_free;
1069 132120 : char dummy = 1;
1070 : zend_fcall_info fcall_info;
1071 : zend_fcall_info_cache fcall_cache;
1072 : ulong hash;
1073 :
1074 132120 : if (name.v == NULL || !name_length) {
1075 67 : return FAILURE;
1076 : }
1077 :
1078 132053 : if (do_normalize) {
1079 132053 : lc_free = lc_name = zend_u_str_case_fold(type, name, name_length, 1, &lc_name_len);
1080 : } else {
1081 0 : lc_name = name;
1082 0 : lc_name_len = name_length;
1083 : }
1084 :
1085 : /* Ignore leading "\" */
1086 132062 : if (type == IS_UNICODE &&
1087 : lc_name.u[0] == '\\') {
1088 9 : lc_name.u += 1;
1089 9 : lc_name_len -= 1;
1090 132044 : } else if (type == IS_STRING &&
1091 : lc_name.s[0] == '\\') {
1092 2 : lc_name.s += 1;
1093 2 : lc_name_len -= 1;
1094 : }
1095 :
1096 132053 : hash = zend_u_inline_hash_func(type, lc_name, lc_name_len + 1);
1097 :
1098 132053 : if (zend_u_hash_quick_find(EG(class_table), type, lc_name, lc_name_len + 1, hash, (void **) ce) == SUCCESS) {
1099 131515 : if (do_normalize) {
1100 131515 : efree(lc_free.v);
1101 : }
1102 131515 : return SUCCESS;
1103 : }
1104 :
1105 : /* The compiler is not-reentrant. Make sure we __autoload() only during run-time
1106 : * (doesn't impact fuctionality of __autoload()
1107 : */
1108 538 : if (!autoload_name.v || zend_is_compiling(TSRMLS_C)) {
1109 283 : if (do_normalize) {
1110 283 : efree(lc_free.v);
1111 : }
1112 283 : return FAILURE;
1113 : }
1114 :
1115 255 : if (EG(in_autoload) == NULL) {
1116 138 : ALLOC_HASHTABLE(EG(in_autoload));
1117 138 : zend_u_hash_init(EG(in_autoload), 0, NULL, NULL, 0, UG(unicode));
1118 : }
1119 :
1120 255 : if (zend_u_hash_quick_add(EG(in_autoload), type, lc_name, lc_name_len + 1, hash, (void**)&dummy, sizeof(char), NULL) == FAILURE) {
1121 4 : if (do_normalize) {
1122 4 : efree(lc_free.v);
1123 : }
1124 4 : return FAILURE;
1125 : }
1126 :
1127 251 : ZVAL_ASCII_STRINGL(&autoload_function, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1, 0);
1128 :
1129 251 : ALLOC_ZVAL(class_name_ptr);
1130 251 : INIT_PZVAL(class_name_ptr);
1131 251 : ZVAL_ZSTRL(class_name_ptr, type, autoload_name, name_length, 1);
1132 :
1133 251 : args[0] = &class_name_ptr;
1134 :
1135 251 : fcall_info.size = sizeof(fcall_info);
1136 251 : fcall_info.function_table = EG(function_table);
1137 251 : fcall_info.function_name = &autoload_function;
1138 251 : fcall_info.symbol_table = NULL;
1139 251 : fcall_info.retval_ptr_ptr = &retval_ptr;
1140 251 : fcall_info.param_count = 1;
1141 251 : fcall_info.params = args;
1142 251 : fcall_info.object_ptr = NULL;
1143 251 : fcall_info.no_separation = 1;
1144 :
1145 251 : fcall_cache.initialized = EG(autoload_func) ? 1 : 0;
1146 251 : fcall_cache.function_handler = EG(autoload_func);
1147 251 : fcall_cache.calling_scope = NULL;
1148 251 : fcall_cache.called_scope = NULL;
1149 251 : fcall_cache.object_ptr = NULL;
1150 :
1151 251 : zend_exception_save(TSRMLS_C);
1152 251 : retval = zend_call_function(&fcall_info, &fcall_cache TSRMLS_CC);
1153 248 : zend_exception_restore(TSRMLS_C);
1154 :
1155 248 : EG(autoload_func) = fcall_cache.function_handler;
1156 :
1157 248 : zval_dtor(&autoload_function);
1158 :
1159 248 : zval_ptr_dtor(&class_name_ptr);
1160 :
1161 248 : zend_u_hash_quick_del(EG(in_autoload), type, lc_name, lc_name_len + 1, hash);
1162 :
1163 248 : if (retval_ptr) {
1164 111 : zval_ptr_dtor(&retval_ptr);
1165 : }
1166 :
1167 248 : if (retval == FAILURE) {
1168 123 : if (do_normalize) {
1169 123 : efree(lc_free.v);
1170 : }
1171 123 : return FAILURE;
1172 : }
1173 :
1174 125 : retval = zend_u_hash_quick_find(EG(class_table), type, lc_name, lc_name_len + 1, hash, (void **) ce);
1175 125 : if (do_normalize) {
1176 125 : efree(lc_free.v);
1177 : }
1178 125 : return retval;
1179 : }
1180 : /* }}} */
1181 :
1182 : ZEND_API int zend_u_lookup_class(zend_uchar type, zstr name, int name_length, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
1183 3177 : {
1184 3177 : return zend_u_lookup_class_ex(type, name, name_length, name, 1, ce TSRMLS_CC);
1185 : }
1186 : /* }}} */
1187 :
1188 : ZEND_API int zend_lookup_class_ex(char *name, int name_length, char *autoload_name, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
1189 0 : {
1190 0 : return zend_u_lookup_class_ex(IS_STRING, ZSTR(name), name_length, ZSTR(autoload_name), 1, ce TSRMLS_CC);
1191 : }
1192 : /* }}} */
1193 :
1194 : ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
1195 90 : {
1196 90 : return zend_u_lookup_class(IS_STRING, ZSTR(name), name_length, ce TSRMLS_CC);
1197 : }
1198 : /* }}} */
1199 :
1200 : ZEND_API int zend_u_eval_stringl(zend_uchar type, zstr string, int str_len, zval *retval_ptr, char *string_name TSRMLS_DC) /* {{{ */
1201 113 : {
1202 : zval pv;
1203 : zend_op_array *new_op_array;
1204 113 : zend_op_array *original_active_op_array = EG(active_op_array);
1205 : zend_uint original_compiler_options;
1206 : int retval;
1207 :
1208 113 : if (type == IS_UNICODE) {
1209 0 : UChar *str = string.u;
1210 :
1211 0 : if (retval_ptr) {
1212 0 : Z_USTRLEN(pv) = str_len + sizeof("return ;") - 1;
1213 0 : Z_USTRVAL(pv) = eumalloc(Z_USTRLEN(pv) + 1);
1214 0 : u_memcpy(Z_USTRVAL(pv), u_return, sizeof("return ") - 1);
1215 0 : u_memcpy(Z_USTRVAL(pv) + sizeof("return ") - 1, str, str_len);
1216 0 : Z_USTRVAL(pv)[Z_USTRLEN(pv) - 1] = 0x3B /*';'*/;
1217 0 : Z_USTRVAL(pv)[Z_USTRLEN(pv)] = 0;
1218 : } else {
1219 0 : Z_USTRLEN(pv) = str_len;
1220 0 : Z_USTRVAL(pv) = str;
1221 : }
1222 : } else {
1223 113 : char *str = string.s;
1224 :
1225 113 : if (retval_ptr) {
1226 30 : Z_STRLEN(pv) = str_len + sizeof("return ;") - 1;
1227 30 : Z_STRVAL(pv) = emalloc(Z_STRLEN(pv) + 1);
1228 30 : memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1);
1229 30 : memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len);
1230 30 : Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';';
1231 30 : Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0';
1232 : } else {
1233 83 : Z_STRLEN(pv) = str_len;
1234 83 : Z_STRVAL(pv) = str;
1235 : }
1236 : }
1237 113 : Z_TYPE(pv) = type;
1238 :
1239 : /*printf("Evaluating '%s'\n", Z_STRVAL(pv));*/
1240 :
1241 113 : original_compiler_options = CG(compiler_options);
1242 113 : CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
1243 113 : new_op_array = zend_compile_string(&pv, string_name TSRMLS_CC);
1244 113 : CG(compiler_options) = original_compiler_options;
1245 :
1246 113 : if (new_op_array) {
1247 107 : zval *local_retval_ptr=NULL;
1248 107 : zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
1249 107 : zend_op **original_opline_ptr = EG(opline_ptr);
1250 107 : int orig_interactive = CG(interactive);
1251 :
1252 107 : EG(return_value_ptr_ptr) = &local_retval_ptr;
1253 107 : EG(active_op_array) = new_op_array;
1254 107 : EG(no_extensions)=1;
1255 107 : if (!EG(active_symbol_table)) {
1256 3 : zend_rebuild_symbol_table(TSRMLS_C);
1257 : }
1258 107 : CG(interactive) = 0;
1259 :
1260 107 : zend_execute(new_op_array TSRMLS_CC);
1261 :
1262 107 : CG(interactive) = orig_interactive;
1263 107 : if (local_retval_ptr) {
1264 107 : if (retval_ptr) {
1265 26 : COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr);
1266 : } else {
1267 81 : zval_ptr_dtor(&local_retval_ptr);
1268 : }
1269 : } else {
1270 0 : if (retval_ptr) {
1271 0 : INIT_ZVAL(*retval_ptr);
1272 : }
1273 : }
1274 :
1275 107 : EG(no_extensions)=0;
1276 107 : EG(opline_ptr) = original_opline_ptr;
1277 107 : EG(active_op_array) = original_active_op_array;
1278 107 : destroy_op_array(new_op_array TSRMLS_CC);
1279 107 : efree(new_op_array);
1280 107 : EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
1281 107 : retval = SUCCESS;
1282 : } else {
1283 6 : retval = FAILURE;
1284 : }
1285 113 : if (retval_ptr) {
1286 30 : zval_dtor(&pv);
1287 : }
1288 113 : return retval;
1289 : }
1290 : /* }}} */
1291 :
1292 : ZEND_API int zend_u_eval_string(zend_uchar type, zstr str, zval *retval_ptr, char *string_name TSRMLS_DC) /* {{{ */
1293 0 : {
1294 0 : return zend_u_eval_stringl(type, str, ZSTR_LEN(type, str), retval_ptr, string_name TSRMLS_CC);
1295 : }
1296 : /* }}} */
1297 :
1298 : ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *string_name TSRMLS_DC) /* {{{ */
1299 94 : {
1300 94 : return zend_u_eval_stringl(IS_STRING, ZSTR(str), str_len, retval_ptr, string_name TSRMLS_CC);
1301 : }
1302 : /* }}} */
1303 :
1304 : ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) /* {{{ */
1305 0 : {
1306 0 : return zend_u_eval_stringl(IS_STRING, ZSTR(str), strlen(str), retval_ptr, string_name TSRMLS_CC);
1307 : }
1308 : /* }}} */
1309 :
1310 : ZEND_API int zend_u_eval_stringl_ex(zend_uchar type, zstr str, int str_len, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) /* {{{ */
1311 19 : {
1312 : int result;
1313 :
1314 19 : result = zend_u_eval_stringl(type, str, str_len, retval_ptr, string_name TSRMLS_CC);
1315 19 : if (handle_exceptions && EG(exception)) {
1316 0 : zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
1317 0 : result = FAILURE;
1318 : }
1319 19 : return result;
1320 : }
1321 : /* }}} */
1322 :
1323 : ZEND_API int zend_u_eval_string_ex(zend_uchar type, zstr str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) /* {{{ */
1324 0 : {
1325 0 : return zend_u_eval_stringl_ex(type, str, ZSTR_LEN(type, str), retval_ptr, string_name, handle_exceptions TSRMLS_CC);
1326 : }
1327 : /* }}} */
1328 :
1329 : ZEND_API int zend_eval_stringl_ex(char *str, int str_len, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) /* {{{ */
1330 0 : {
1331 0 : return zend_u_eval_stringl_ex(IS_STRING, ZSTR(str), str_len, retval_ptr, string_name, handle_exceptions TSRMLS_CC);
1332 : }
1333 : /* }}} */
1334 :
1335 : ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) /* {{{ */
1336 19 : {
1337 19 : return zend_u_eval_stringl_ex(IS_STRING, ZSTR(str), strlen(str), retval_ptr, string_name, handle_exceptions TSRMLS_CC);
1338 : }
1339 : /* }}} */
1340 :
1341 : void execute_new_code(TSRMLS_D) /* {{{ */
1342 0 : {
1343 : zend_op *opline, *end;
1344 : zend_op *ret_opline;
1345 : int orig_interactive;
1346 :
1347 0 : if (!(CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE)
1348 : || CG(active_op_array)->backpatch_count>0
1349 : || CG(active_op_array)->function_name.v
1350 : || CG(active_op_array)->type!=ZEND_USER_FUNCTION) {
1351 0 : return;
1352 : }
1353 :
1354 0 : ret_opline = get_next_op(CG(active_op_array) TSRMLS_CC);
1355 0 : ret_opline->opcode = ZEND_RETURN;
1356 0 : ret_opline->op1.op_type = IS_CONST;
1357 0 : INIT_ZVAL(ret_opline->op1.u.constant);
1358 0 : SET_UNUSED(ret_opline->op2);
1359 :
1360 0 : if (!CG(active_op_array)->start_op) {
1361 0 : CG(active_op_array)->start_op = CG(active_op_array)->opcodes;
1362 : }
1363 :
1364 0 : opline=CG(active_op_array)->start_op;
1365 0 : end=CG(active_op_array)->opcodes+CG(active_op_array)->last;
1366 :
1367 0 : while (opline<end) {
1368 0 : if (opline->op1.op_type == IS_CONST) {
1369 0 : Z_SET_ISREF(opline->op1.u.constant);
1370 0 : Z_SET_REFCOUNT(opline->op1.u.constant, 2); /* Make sure is_ref won't be reset */
1371 : }
1372 0 : if (opline->op2.op_type == IS_CONST) {
1373 0 : Z_SET_ISREF(opline->op2.u.constant);
1374 0 : Z_SET_REFCOUNT(opline->op2.u.constant, 2);
1375 : }
1376 0 : switch (opline->opcode) {
1377 : case ZEND_GOTO:
1378 0 : if (Z_TYPE(opline->op2.u.constant) != IS_LONG) {
1379 0 : zend_resolve_goto_label(CG(active_op_array), opline, 1 TSRMLS_CC);
1380 : }
1381 : /* break omitted intentionally */
1382 : case ZEND_JMP:
1383 0 : opline->op1.u.jmp_addr = &CG(active_op_array)->opcodes[opline->op1.u.opline_num];
1384 0 : break;
1385 : case ZEND_JMPZ:
1386 : case ZEND_JMPNZ:
1387 : case ZEND_JMPZ_EX:
1388 : case ZEND_JMPNZ_EX:
1389 : case ZEND_JMP_SET:
1390 0 : opline->op2.u.jmp_addr = &CG(active_op_array)->opcodes[opline->op2.u.opline_num];
1391 : break;
1392 : }
1393 0 : ZEND_VM_SET_OPCODE_HANDLER(opline);
1394 0 : opline++;
1395 : }
1396 :
1397 0 : zend_release_labels(TSRMLS_C);
1398 :
1399 0 : EG(return_value_ptr_ptr) = NULL;
1400 0 : EG(active_op_array) = CG(active_op_array);
1401 0 : orig_interactive = CG(interactive);
1402 0 : CG(interactive) = 0;
1403 0 : zend_execute(CG(active_op_array) TSRMLS_CC);
1404 0 : CG(interactive) = orig_interactive;
1405 :
1406 0 : if (EG(exception)) {
1407 0 : zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
1408 : }
1409 :
1410 0 : CG(active_op_array)->last -= 1; /* get rid of that ZEND_RETURN */
1411 0 : CG(active_op_array)->start_op = CG(active_op_array)->opcodes+CG(active_op_array)->last;
1412 : }
1413 : /* }}} */
1414 :
1415 : ZEND_API void zend_timeout(int dummy) /* {{{ */
1416 3 : {
1417 : TSRMLS_FETCH();
1418 :
1419 3 : if (zend_on_timeout) {
1420 3 : zend_on_timeout(EG(timeout_seconds) TSRMLS_CC);
1421 : }
1422 :
1423 3 : zend_error(E_ERROR, "Maximum execution time of %d second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
1424 0 : }
1425 : /* }}} */
1426 :
1427 : #ifdef ZEND_WIN32
1428 : static LRESULT CALLBACK zend_timeout_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) /* {{{ */
1429 : {
1430 : switch (message) {
1431 : case WM_DESTROY:
1432 : PostQuitMessage(0);
1433 : break;
1434 : case WM_REGISTER_ZEND_TIMEOUT:
1435 : /* wParam is the thread id pointer, lParam is the timeout amount in seconds */
1436 : if (lParam == 0) {
1437 : KillTimer(timeout_window, wParam);
1438 : } else {
1439 : #ifdef ZTS
1440 : void ***tsrm_ls;
1441 : #endif
1442 : SetTimer(timeout_window, wParam, lParam*1000, NULL);
1443 : #ifdef ZTS
1444 : tsrm_ls = ts_resource_ex(0, &wParam);
1445 : if (!tsrm_ls) {
1446 : /* shouldn't normally happen */
1447 : break;
1448 : }
1449 : #endif
1450 : EG(timed_out) = 0;
1451 : }
1452 : break;
1453 : case WM_UNREGISTER_ZEND_TIMEOUT:
1454 : /* wParam is the thread id pointer */
1455 : KillTimer(timeout_window, wParam);
1456 : break;
1457 : case WM_TIMER: {
1458 : #ifdef ZTS
1459 : void ***tsrm_ls;
1460 :
1461 : tsrm_ls = ts_resource_ex(0, &wParam);
1462 : if (!tsrm_ls) {
1463 : /* Thread died before receiving its timeout? */
1464 : break;
1465 : }
1466 : #endif
1467 : KillTimer(timeout_window, wParam);
1468 : EG(timed_out) = 1;
1469 : }
1470 : break;
1471 : default:
1472 : return DefWindowProc(hWnd, message, wParam, lParam);
1473 : }
1474 : return 0;
1475 : }
1476 : /* }}} */
1477 :
1478 : static unsigned __stdcall timeout_thread_proc(void *pArgs) /* {{{ */
1479 : {
1480 : MSG message;
1481 :
1482 : wc.style=0;
1483 : wc.lpfnWndProc = zend_timeout_WndProc;
1484 : wc.cbClsExtra=0;
1485 : wc.cbWndExtra=0;
1486 : wc.hInstance=NULL;
1487 : wc.hIcon=NULL;
1488 : wc.hCursor=NULL;
1489 : wc.hbrBackground=(HBRUSH)(COLOR_BACKGROUND + 5);
1490 : wc.lpszMenuName=NULL;
1491 : wc.lpszClassName = "Zend Timeout Window";
1492 : if (!RegisterClass(&wc)) {
1493 : return -1;
1494 : }
1495 : timeout_window = CreateWindow(wc.lpszClassName, wc.lpszClassName, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
1496 : SetEvent(timeout_thread_event);
1497 : while (GetMessage(&message, NULL, 0, 0)) {
1498 : SendMessage(timeout_window, message.message, message.wParam, message.lParam);
1499 : if (message.message == WM_QUIT) {
1500 : break;
1501 : }
1502 : }
1503 : DestroyWindow(timeout_window);
1504 : UnregisterClass(wc.lpszClassName, NULL);
1505 : SetEvent(timeout_thread_handle);
1506 : return 0;
1507 : }
1508 : /* }}} */
1509 :
1510 : void zend_init_timeout_thread(void) /* {{{ */
1511 : {
1512 : timeout_thread_event = CreateEvent(NULL, FALSE, FALSE, NULL);
1513 : timeout_thread_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
1514 : _beginthreadex(NULL, 0, timeout_thread_proc, NULL, 0, &timeout_thread_id);
1515 : WaitForSingleObject(timeout_thread_event, INFINITE);
1516 : }
1517 : /* }}} */
1518 :
1519 : void zend_shutdown_timeout_thread(void) /* {{{ */
1520 : {
1521 : if (!timeout_thread_initialized) {
1522 : return;
1523 : }
1524 : PostThreadMessage(timeout_thread_id, WM_QUIT, 0, 0);
1525 :
1526 : /* Wait for thread termination */
1527 : WaitForSingleObject(timeout_thread_handle, 5000);
1528 : CloseHandle(timeout_thread_handle);
1529 : timeout_thread_initialized = 0;
1530 : }
1531 : /* }}} */
1532 :
1533 : #endif
1534 :
1535 : /* This one doesn't exists on QNX */
1536 : #ifndef SIGPROF
1537 : #define SIGPROF 27
1538 : #endif
1539 :
1540 : void zend_set_timeout(long seconds, int reset_signals) /* {{{ */
1541 17028 : {
1542 : TSRMLS_FETCH();
1543 :
1544 17028 : EG(timeout_seconds) = seconds;
1545 : #ifdef ZEND_WIN32
1546 : if(!seconds) {
1547 : return;
1548 : }
1549 : if (timeout_thread_initialized == 0 && InterlockedIncrement(&timeout_thread_initialized) == 1) {
1550 : /* We start up this process-wide thread here and not in zend_startup(), because if Zend
1551 : * is initialized inside a DllMain(), you're not supposed to start threads from it.
1552 : */
1553 : zend_init_timeout_thread();
1554 : }
1555 : PostThreadMessage(timeout_thread_id, WM_REGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) seconds);
1556 : #else
1557 : # ifdef HAVE_SETITIMER
1558 : {
1559 : struct itimerval t_r; /* timeout requested */
1560 : sigset_t sigset;
1561 17028 : if(seconds) {
1562 365 : t_r.it_value.tv_sec = seconds;
1563 365 : t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
1564 :
1565 : # ifdef __CYGWIN__
1566 : setitimer(ITIMER_REAL, &t_r, NULL);
1567 : }
1568 : if(reset_signals) {
1569 : signal(SIGALRM, zend_timeout);
1570 : sigemptyset(&sigset);
1571 : sigaddset(&sigset, SIGALRM);
1572 : }
1573 : # else
1574 365 : setitimer(ITIMER_PROF, &t_r, NULL);
1575 : }
1576 17028 : if(reset_signals) {
1577 16996 : signal(SIGPROF, zend_timeout);
1578 16996 : sigemptyset(&sigset);
1579 16996 : sigaddset(&sigset, SIGPROF);
1580 : }
1581 : # endif
1582 17028 : if(reset_signals) {
1583 16996 : sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1584 : }
1585 : }
1586 : # endif
1587 : #endif
1588 17028 : }
1589 : /* }}} */
1590 :
1591 : void zend_unset_timeout(TSRMLS_D) /* {{{ */
1592 17057 : {
1593 : #ifdef ZEND_WIN32
1594 : if(timeout_thread_initialized) {
1595 : PostThreadMessage(timeout_thread_id, WM_UNREGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) 0);
1596 : }
1597 : #else
1598 : # ifdef HAVE_SETITIMER
1599 17057 : if (EG(timeout_seconds)) {
1600 : struct itimerval no_timeout;
1601 :
1602 359 : 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;
1603 :
1604 : #ifdef __CYGWIN__
1605 : setitimer(ITIMER_REAL, &no_timeout, NULL);
1606 : #else
1607 359 : setitimer(ITIMER_PROF, &no_timeout, NULL);
1608 : #endif
1609 : }
1610 : # endif
1611 : #endif
1612 17057 : }
1613 : /* }}} */
1614 :
1615 : ZEND_API zend_class_entry *zend_u_fetch_class(zend_uchar type, zstr class_name, uint class_name_len, int fetch_type TSRMLS_DC) /* {{{ */
1616 131181 : {
1617 : zend_class_entry **pce;
1618 131181 : int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) ? 0 : 1;
1619 131181 : int silent = (fetch_type & ZEND_FETCH_CLASS_SILENT) != 0;
1620 131181 : zstr lcname = class_name;
1621 :
1622 131181 : fetch_type &= ZEND_FETCH_CLASS_MASK;
1623 :
1624 131187 : check_fetch_type:
1625 131187 : switch (fetch_type) {
1626 : case ZEND_FETCH_CLASS_SELF:
1627 1093 : if (!EG(scope)) {
1628 0 : zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
1629 : }
1630 1093 : return EG(scope);
1631 : case ZEND_FETCH_CLASS_PARENT:
1632 1118 : if (!EG(scope)) {
1633 0 : zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
1634 : }
1635 1118 : if (!EG(scope)->parent) {
1636 0 : zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");
1637 : }
1638 1118 : return EG(scope)->parent;
1639 : case ZEND_FETCH_CLASS_STATIC:
1640 88 : if (!EG(called_scope)) {
1641 0 : zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
1642 : }
1643 88 : return EG(called_scope);
1644 : case ZEND_FETCH_CLASS_AUTO: {
1645 1300 : fetch_type = zend_get_class_fetch_type(type, lcname, class_name_len);
1646 1300 : if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) {
1647 6 : if (lcname.v != class_name.v) {
1648 0 : efree(lcname.v);
1649 : }
1650 6 : goto check_fetch_type;
1651 : }
1652 : }
1653 : break;
1654 : }
1655 :
1656 128882 : if (zend_u_lookup_class_ex(type, lcname, class_name_len, (use_autoload ? class_name : NULL_ZSTR), 1, &pce TSRMLS_CC) == FAILURE) {
1657 37 : if (use_autoload) {
1658 29 : if (!silent && !EG(exception)) {
1659 25 : if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
1660 2 : zend_error(E_ERROR, "Interface '%R' not found", type, class_name);
1661 : } else {
1662 23 : zend_error(E_ERROR, "Class '%R' not found", type, class_name);
1663 : }
1664 : }
1665 : }
1666 12 : return NULL;
1667 : }
1668 128843 : return *pce;
1669 : }
1670 : /* }}} */
1671 :
1672 : zend_class_entry *zend_fetch_class(char *class_name, uint class_name_len, int fetch_type TSRMLS_DC) /* {{{ */
1673 2312 : {
1674 2312 : return zend_u_fetch_class(IS_STRING, ZSTR(class_name), class_name_len, fetch_type TSRMLS_CC);
1675 : }
1676 : /* }}} */
1677 :
1678 : #define MAX_ABSTRACT_INFO_CNT 3
1679 : #define MAX_ABSTRACT_INFO_FMT "%v%s%v%s"
1680 : #define DISPLAY_ABSTRACT_FN(idx) \
1681 : ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : EMPTY_ZSTR, \
1682 : ai.afn[idx] ? "::" : "", \
1683 : ai.afn[idx] ? ai.afn[idx]->common.function_name : EMPTY_ZSTR, \
1684 : ai.afn[idx] && ai.afn[idx + 1] ? ", " : (ai.afn[idx] && ai.cnt > MAX_ABSTRACT_INFO_CNT ? ", ..." : "")
1685 :
1686 : typedef struct _zend_abstract_info {
1687 : zend_function *afn[MAX_ABSTRACT_INFO_CNT + 1];
1688 : int cnt;
1689 : int ctor;
1690 : } zend_abstract_info;
1691 :
1692 : static int zend_verify_abstract_class_function(zend_function *fn, zend_abstract_info *ai TSRMLS_DC) /* {{{ */
1693 11 : {
1694 11 : if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
1695 10 : if (ai->cnt < MAX_ABSTRACT_INFO_CNT) {
1696 10 : ai->afn[ai->cnt] = fn;
1697 : }
1698 10 : if (fn->common.fn_flags & ZEND_ACC_CTOR) {
1699 1 : if (!ai->ctor) {
1700 1 : ai->cnt++;
1701 1 : ai->ctor = 1;
1702 : } else {
1703 0 : ai->afn[ai->cnt] = NULL;
1704 : }
1705 : } else {
1706 9 : ai->cnt++;
1707 : }
1708 : }
1709 11 : return 0;
1710 : }
1711 : /* }}} */
1712 :
1713 : void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */
1714 1065970 : {
1715 : zend_abstract_info ai;
1716 :
1717 1065970 : if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
1718 9 : memset(&ai, 0, sizeof(ai));
1719 :
1720 9 : zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t) zend_verify_abstract_class_function, &ai TSRMLS_CC);
1721 :
1722 9 : if (ai.cnt) {
1723 9 : zend_error(E_ERROR, "Class %v contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")",
1724 : ce->name, ai.cnt,
1725 : ai.cnt > 1 ? "s" : "",
1726 : DISPLAY_ABSTRACT_FN(0),
1727 : DISPLAY_ABSTRACT_FN(1),
1728 : DISPLAY_ABSTRACT_FN(2)
1729 : );
1730 : }
1731 : }
1732 1065961 : }
1733 : /* }}} */
1734 :
1735 : ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC) /* {{{ */
1736 1 : {
1737 : zend_execute_data *ex;
1738 : int i;
1739 :
1740 1 : memset(CG(auto_globals_cache), 0, sizeof(zval**) * zend_hash_num_elements(CG(auto_globals)));
1741 3 : for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
1742 2 : if (ex->op_array && ex->symbol_table == symbol_table) {
1743 1 : for (i = 0; i < ex->op_array->last_var; i++) {
1744 0 : ex->CVs[i] = NULL;
1745 : }
1746 : }
1747 : }
1748 1 : }
1749 : /* }}} */
1750 :
1751 : ZEND_API int zend_u_delete_global_variable(zend_uchar type, zstr name, int name_len TSRMLS_DC) /* {{{ */
1752 253 : {
1753 : zend_execute_data *ex;
1754 253 : ulong hash_value = zend_u_inline_hash_func(type, name, name_len + 1);
1755 : zend_auto_global *auto_global;
1756 :
1757 253 : if (zend_u_hash_quick_find(CG(auto_globals), type, name, name_len + 1, hash_value, (void **)&auto_global) == SUCCESS) {
1758 241 : CG(auto_globals_cache)[auto_global->index] = NULL;
1759 : }
1760 253 : if (zend_u_hash_quick_exists(&EG(symbol_table), type, name, name_len + 1, hash_value)) {
1761 234 : for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
1762 117 : if (ex->op_array && ex->symbol_table == &EG(symbol_table)) {
1763 : int i;
1764 438 : for (i = 0; i < ex->op_array->last_var; i++) {
1765 323 : if (ex->op_array->vars[i].hash_value == hash_value &&
1766 : ex->op_array->vars[i].name_len == name_len &&
1767 : !memcmp(ex->op_array->vars[i].name.v, name.v, USTR_BYTES(type, name_len))
1768 : ) {
1769 2 : ex->CVs[i] = NULL;
1770 2 : break;
1771 : }
1772 : }
1773 : }
1774 : }
1775 117 : return zend_u_hash_quick_del(&EG(symbol_table), type, name, name_len + 1, hash_value);
1776 : }
1777 136 : return FAILURE;
1778 : }
1779 : /* }}} */
1780 :
1781 : ZEND_API int zend_delete_global_variable(char *name, int name_len TSRMLS_DC) /* {{{ */
1782 238 : {
1783 238 : return zend_u_delete_global_variable(IS_STRING, ZSTR(name), name_len TSRMLS_CC);
1784 : }
1785 : /* }}} */
1786 :
1787 : ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
1788 34129 : {
1789 34129 : zend_uchar type = IS_UNICODE;
1790 : zend_uint i;
1791 : zend_execute_data *ex;
1792 :
1793 34129 : if (!EG(active_symbol_table)) {
1794 :
1795 : /* Search for last called user function */
1796 34129 : ex = EG(current_execute_data);
1797 68261 : while (ex && !ex->op_array) {
1798 3 : ex = ex->prev_execute_data;
1799 : }
1800 34129 : if (ex && ex->symbol_table) {
1801 0 : EG(active_symbol_table) = ex->symbol_table;
1802 0 : return;
1803 : }
1804 :
1805 34129 : if (ex && ex->op_array) {
1806 34127 : if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
1807 : /*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
1808 33623 : EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
1809 : } else {
1810 504 : ALLOC_HASHTABLE(EG(active_symbol_table));
1811 504 : zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
1812 : /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/
1813 : }
1814 34127 : ex->symbol_table = EG(active_symbol_table);
1815 :
1816 34127 : if (ex->op_array->this_var != -1 &&
1817 : !ex->CVs[ex->op_array->this_var] &&
1818 : EG(This)) {
1819 0 : ex->CVs[ex->op_array->this_var] = (zval**)ex->CVs + ex->op_array->last_var + ex->op_array->this_var;
1820 0 : *ex->CVs[ex->op_array->this_var] = EG(This);
1821 : }
1822 1444984 : for (i = 0; i < (zend_uint) ex->op_array->last_var; i++) {
1823 1410857 : if (ex->CVs[i]) {
1824 608775 : zend_u_hash_quick_update(EG(active_symbol_table),
1825 : type,
1826 : ex->op_array->vars[i].name,
1827 : ex->op_array->vars[i].name_len + 1,
1828 : ex->op_array->vars[i].hash_value,
1829 : (void**)ex->CVs[i],
1830 : sizeof(zval*),
1831 : (void**)&ex->CVs[i]);
1832 : }
1833 : }
1834 : }
1835 : }
1836 : }
1837 : /* }}} */
1838 :
1839 : /*
1840 : * Local variables:
1841 : * tab-width: 4
1842 : * c-basic-offset: 4
1843 : * indent-tabs-mode: t
1844 : * End:
1845 : */
|