1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 2.00 of the Zend license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.zend.com/license/2_00.txt. |
11 | If you did not receive a copy of the Zend license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@zend.com so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Andi Gutmans <andi@zend.com> |
16 | Zeev Suraski <zeev@zend.com> |
17 +----------------------------------------------------------------------+
18 */
19
20 /* $Id$ */
21
22 #include "zend.h"
23 #include "zend_extensions.h"
24 #include "zend_modules.h"
25 #include "zend_constants.h"
26 #include "zend_list.h"
27 #include "zend_API.h"
28 #include "zend_exceptions.h"
29 #include "zend_builtin_functions.h"
30 #include "zend_ini.h"
31 #include "zend_vm.h"
32 #include "zend_dtrace.h"
33
34 #ifdef ZTS
35 # define GLOBAL_FUNCTION_TABLE global_function_table
36 # define GLOBAL_CLASS_TABLE global_class_table
37 # define GLOBAL_CONSTANTS_TABLE global_constants_table
38 # define GLOBAL_AUTO_GLOBALS_TABLE global_auto_globals_table
39 #else
40 # define GLOBAL_FUNCTION_TABLE CG(function_table)
41 # define GLOBAL_CLASS_TABLE CG(class_table)
42 # define GLOBAL_AUTO_GLOBALS_TABLE CG(auto_globals)
43 # define GLOBAL_CONSTANTS_TABLE EG(zend_constants)
44 #endif
45
46 /* true multithread-shared globals */
47 ZEND_API zend_class_entry *zend_standard_class_def = NULL;
48 ZEND_API int (*zend_printf)(const char *format, ...);
49 ZEND_API zend_write_func_t zend_write;
50 ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path TSRMLS_DC);
51 ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
52 ZEND_API void (*zend_block_interruptions)(void);
53 ZEND_API void (*zend_unblock_interruptions)(void);
54 ZEND_API void (*zend_ticks_function)(int ticks);
55 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
56 int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
57 ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
58 ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
59
60 void (*zend_on_timeout)(int seconds TSRMLS_DC);
61
62 static void (*zend_message_dispatcher_p)(long message, const void *data TSRMLS_DC);
63 static int (*zend_get_configuration_directive_p)(const char *name, uint name_length, zval *contents);
64
ZEND_INI_MH(OnUpdateErrorReporting)65 static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
66 {
67 if (!new_value) {
68 EG(error_reporting) = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED;
69 } else {
70 EG(error_reporting) = atoi(new_value);
71 }
72 return SUCCESS;
73 }
74 /* }}} */
75
ZEND_INI_MH(OnUpdateGCEnabled)76 static ZEND_INI_MH(OnUpdateGCEnabled) /* {{{ */
77 {
78 OnUpdateBool(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
79
80 if (GC_G(gc_enabled)) {
81 gc_init(TSRMLS_C);
82 }
83
84 return SUCCESS;
85 }
86 /* }}} */
87
ZEND_INI_MH(OnUpdateScriptEncoding)88 static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */
89 {
90 if (!CG(multibyte)) {
91 return FAILURE;
92 }
93 if (!zend_multibyte_get_functions(TSRMLS_C)) {
94 return SUCCESS;
95 }
96 return zend_multibyte_set_script_encoding_by_string(new_value, new_value_length TSRMLS_CC);
97 }
98 /* }}} */
99
100
101 ZEND_INI_BEGIN()
102 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
103 STD_ZEND_INI_BOOLEAN("zend.enable_gc", "1", ZEND_INI_ALL, OnUpdateGCEnabled, gc_enabled, zend_gc_globals, gc_globals)
104 STD_ZEND_INI_BOOLEAN("zend.multibyte", "0", ZEND_INI_PERDIR, OnUpdateBool, multibyte, zend_compiler_globals, compiler_globals)
105 ZEND_INI_ENTRY("zend.script_encoding", NULL, ZEND_INI_ALL, OnUpdateScriptEncoding)
106 STD_ZEND_INI_BOOLEAN("zend.detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
107 #ifdef ZEND_SIGNALS
108 STD_ZEND_INI_BOOLEAN("zend.signal_check", "0", ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals)
109 #endif
110 ZEND_INI_END()
111
112
113 #ifdef ZTS
114 ZEND_API int compiler_globals_id;
115 ZEND_API int executor_globals_id;
116 static HashTable *global_function_table = NULL;
117 static HashTable *global_class_table = NULL;
118 static HashTable *global_constants_table = NULL;
119 static HashTable *global_auto_globals_table = NULL;
120 static HashTable *global_persistent_list = NULL;
121 #endif
122
123 ZEND_API zend_utility_values zend_uv;
124
125 ZEND_API zval zval_used_for_init; /* True global variable */
126
127 /* version information */
128 static char *zend_version_info;
129 static uint zend_version_info_length;
130 #define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright (c) 1998-2014 Zend Technologies\n"
131 #define PRINT_ZVAL_INDENT 4
132
print_hash(zend_write_func_t write_func,HashTable * ht,int indent,zend_bool is_object TSRMLS_DC)133 static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent, zend_bool is_object TSRMLS_DC) /* {{{ */
134 {
135 zval **tmp;
136 char *string_key;
137 HashPosition iterator;
138 ulong num_key;
139 uint str_len;
140 int i;
141
142 for (i = 0; i < indent; i++) {
143 ZEND_PUTS_EX(" ");
144 }
145 ZEND_PUTS_EX("(\n");
146 indent += PRINT_ZVAL_INDENT;
147 zend_hash_internal_pointer_reset_ex(ht, &iterator);
148 while (zend_hash_get_current_data_ex(ht, (void **) &tmp, &iterator) == SUCCESS) {
149 for (i = 0; i < indent; i++) {
150 ZEND_PUTS_EX(" ");
151 }
152 ZEND_PUTS_EX("[");
153 switch (zend_hash_get_current_key_ex(ht, &string_key, &str_len, &num_key, 0, &iterator)) {
154 case HASH_KEY_IS_STRING:
155 if (is_object) {
156 const char *prop_name, *class_name;
157 int mangled = zend_unmangle_property_name(string_key, str_len - 1, &class_name, &prop_name);
158
159 ZEND_PUTS_EX(prop_name);
160 if (class_name && mangled == SUCCESS) {
161 if (class_name[0]=='*') {
162 ZEND_PUTS_EX(":protected");
163 } else {
164 ZEND_PUTS_EX(":");
165 ZEND_PUTS_EX(class_name);
166 ZEND_PUTS_EX(":private");
167 }
168 }
169 } else {
170 ZEND_WRITE_EX(string_key, str_len-1);
171 }
172 break;
173 case HASH_KEY_IS_LONG:
174 {
175 char key[25];
176 snprintf(key, sizeof(key), "%ld", num_key);
177 ZEND_PUTS_EX(key);
178 }
179 break;
180 }
181 ZEND_PUTS_EX("] => ");
182 zend_print_zval_r_ex(write_func, *tmp, indent+PRINT_ZVAL_INDENT TSRMLS_CC);
183 ZEND_PUTS_EX("\n");
184 zend_hash_move_forward_ex(ht, &iterator);
185 }
186 indent -= PRINT_ZVAL_INDENT;
187 for (i = 0; i < indent; i++) {
188 ZEND_PUTS_EX(" ");
189 }
190 ZEND_PUTS_EX(")\n");
191 }
192 /* }}} */
193
print_flat_hash(HashTable * ht TSRMLS_DC)194 static void print_flat_hash(HashTable *ht TSRMLS_DC) /* {{{ */
195 {
196 zval **tmp;
197 char *string_key;
198 HashPosition iterator;
199 ulong num_key;
200 uint str_len;
201 int i = 0;
202
203 zend_hash_internal_pointer_reset_ex(ht, &iterator);
204 while (zend_hash_get_current_data_ex(ht, (void **) &tmp, &iterator) == SUCCESS) {
205 if (i++ > 0) {
206 ZEND_PUTS(",");
207 }
208 ZEND_PUTS("[");
209 switch (zend_hash_get_current_key_ex(ht, &string_key, &str_len, &num_key, 0, &iterator)) {
210 case HASH_KEY_IS_STRING:
211 ZEND_PUTS(string_key);
212 break;
213 case HASH_KEY_IS_LONG:
214 zend_printf("%ld", num_key);
215 break;
216 }
217 ZEND_PUTS("] => ");
218 zend_print_flat_zval_r(*tmp TSRMLS_CC);
219 zend_hash_move_forward_ex(ht, &iterator);
220 }
221 }
222 /* }}} */
223
zend_make_printable_zval(zval * expr,zval * expr_copy,int * use_copy)224 ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy) /* {{{ */
225 {
226 if (Z_TYPE_P(expr)==IS_STRING) {
227 *use_copy = 0;
228 return;
229 }
230 switch (Z_TYPE_P(expr)) {
231 case IS_NULL:
232 Z_STRLEN_P(expr_copy) = 0;
233 Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
234 break;
235 case IS_BOOL:
236 if (Z_LVAL_P(expr)) {
237 Z_STRLEN_P(expr_copy) = 1;
238 Z_STRVAL_P(expr_copy) = estrndup("1", 1);
239 } else {
240 Z_STRLEN_P(expr_copy) = 0;
241 Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
242 }
243 break;
244 case IS_RESOURCE:
245 Z_STRVAL_P(expr_copy) = (char *) emalloc(sizeof("Resource id #") - 1 + MAX_LENGTH_OF_LONG);
246 Z_STRLEN_P(expr_copy) = snprintf(Z_STRVAL_P(expr_copy), sizeof("Resource id #") - 1 + MAX_LENGTH_OF_LONG, "Resource id #%ld", Z_LVAL_P(expr));
247 break;
248 case IS_ARRAY:
249 zend_error(E_NOTICE, "Array to string conversion");
250 Z_STRLEN_P(expr_copy) = sizeof("Array") - 1;
251 Z_STRVAL_P(expr_copy) = estrndup("Array", Z_STRLEN_P(expr_copy));
252 break;
253 case IS_OBJECT:
254 {
255 TSRMLS_FETCH();
256
257 if (zend_std_cast_object_tostring(expr, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
258 break;
259 }
260 if (Z_OBJ_HANDLER_P(expr, cast_object)) {
261 zval *val;
262
263 ALLOC_ZVAL(val);
264 INIT_PZVAL_COPY(val, expr);
265 zval_copy_ctor(val);
266 if (Z_OBJ_HANDLER_P(expr, cast_object)(val, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
267 zval_ptr_dtor(&val);
268 break;
269 }
270 zval_ptr_dtor(&val);
271 }
272 if (!Z_OBJ_HANDLER_P(expr, cast_object) && Z_OBJ_HANDLER_P(expr, get)) {
273 zval *z = Z_OBJ_HANDLER_P(expr, get)(expr TSRMLS_CC);
274
275 Z_ADDREF_P(z);
276 if (Z_TYPE_P(z) != IS_OBJECT) {
277 zend_make_printable_zval(z, expr_copy, use_copy);
278 if (*use_copy) {
279 zval_ptr_dtor(&z);
280 } else {
281 ZVAL_ZVAL(expr_copy, z, 0, 1);
282 *use_copy = 1;
283 }
284 return;
285 }
286 zval_ptr_dtor(&z);
287 }
288 zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", Z_OBJCE_P(expr)->name);
289 Z_STRLEN_P(expr_copy) = 0;
290 Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
291 }
292 break;
293 case IS_DOUBLE:
294 *expr_copy = *expr;
295 zval_copy_ctor(expr_copy);
296 zend_locale_sprintf_double(expr_copy ZEND_FILE_LINE_CC);
297 break;
298 default:
299 *expr_copy = *expr;
300 zval_copy_ctor(expr_copy);
301 convert_to_string(expr_copy);
302 break;
303 }
304 Z_TYPE_P(expr_copy) = IS_STRING;
305 *use_copy = 1;
306 }
307 /* }}} */
308
zend_print_zval(zval * expr,int indent)309 ZEND_API int zend_print_zval(zval *expr, int indent) /* {{{ */
310 {
311 return zend_print_zval_ex(zend_write, expr, indent);
312 }
313 /* }}} */
314
zend_print_zval_ex(zend_write_func_t write_func,zval * expr,int indent)315 ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent) /* {{{ */
316 {
317 zval expr_copy;
318 int use_copy;
319
320 zend_make_printable_zval(expr, &expr_copy, &use_copy);
321 if (use_copy) {
322 expr = &expr_copy;
323 }
324 if (Z_STRLEN_P(expr) == 0) { /* optimize away empty strings */
325 if (use_copy) {
326 zval_dtor(expr);
327 }
328 return 0;
329 }
330 write_func(Z_STRVAL_P(expr), Z_STRLEN_P(expr));
331 if (use_copy) {
332 zval_dtor(expr);
333 }
334 return Z_STRLEN_P(expr);
335 }
336 /* }}} */
337
zend_print_flat_zval_r(zval * expr TSRMLS_DC)338 ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC) /* {{{ */
339 {
340 switch (Z_TYPE_P(expr)) {
341 case IS_ARRAY:
342 ZEND_PUTS("Array (");
343 if (++Z_ARRVAL_P(expr)->nApplyCount>1) {
344 ZEND_PUTS(" *RECURSION*");
345 Z_ARRVAL_P(expr)->nApplyCount--;
346 return;
347 }
348 print_flat_hash(Z_ARRVAL_P(expr) TSRMLS_CC);
349 ZEND_PUTS(")");
350 Z_ARRVAL_P(expr)->nApplyCount--;
351 break;
352 case IS_OBJECT:
353 {
354 HashTable *properties = NULL;
355 const char *class_name = NULL;
356 zend_uint clen;
357
358 if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
359 Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
360 }
361 if (class_name) {
362 zend_printf("%s Object (", class_name);
363 } else {
364 zend_printf("%s Object (", "Unknown Class");
365 }
366 if (class_name) {
367 efree((char*)class_name);
368 }
369 if (Z_OBJ_HANDLER_P(expr, get_properties)) {
370 properties = Z_OBJPROP_P(expr);
371 }
372 if (properties) {
373 if (++properties->nApplyCount>1) {
374 ZEND_PUTS(" *RECURSION*");
375 properties->nApplyCount--;
376 return;
377 }
378 print_flat_hash(properties TSRMLS_CC);
379 properties->nApplyCount--;
380 }
381 ZEND_PUTS(")");
382 break;
383 }
384 default:
385 zend_print_variable(expr);
386 break;
387 }
388 }
389 /* }}} */
390
zend_print_zval_r(zval * expr,int indent TSRMLS_DC)391 ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC) /* {{{ */
392 {
393 zend_print_zval_r_ex(zend_write, expr, indent TSRMLS_CC);
394 }
395 /* }}} */
396
zend_print_zval_r_ex(zend_write_func_t write_func,zval * expr,int indent TSRMLS_DC)397 ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC) /* {{{ */
398 {
399 switch (Z_TYPE_P(expr)) {
400 case IS_ARRAY:
401 ZEND_PUTS_EX("Array\n");
402 if (++Z_ARRVAL_P(expr)->nApplyCount>1) {
403 ZEND_PUTS_EX(" *RECURSION*");
404 Z_ARRVAL_P(expr)->nApplyCount--;
405 return;
406 }
407 print_hash(write_func, Z_ARRVAL_P(expr), indent, 0 TSRMLS_CC);
408 Z_ARRVAL_P(expr)->nApplyCount--;
409 break;
410 case IS_OBJECT:
411 {
412 HashTable *properties;
413 const char *class_name = NULL;
414 zend_uint clen;
415 int is_temp;
416
417 if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
418 Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
419 }
420 if (class_name) {
421 ZEND_PUTS_EX(class_name);
422 } else {
423 ZEND_PUTS_EX("Unknown Class");
424 }
425 ZEND_PUTS_EX(" Object\n");
426 if (class_name) {
427 efree((char*)class_name);
428 }
429 if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) {
430 break;
431 }
432 if (++properties->nApplyCount>1) {
433 ZEND_PUTS_EX(" *RECURSION*");
434 properties->nApplyCount--;
435 return;
436 }
437 print_hash(write_func, properties, indent, 1 TSRMLS_CC);
438 properties->nApplyCount--;
439 if (is_temp) {
440 zend_hash_destroy(properties);
441 efree(properties);
442 }
443 break;
444 }
445 default:
446 zend_print_zval_ex(write_func, expr, indent);
447 break;
448 }
449 }
450 /* }}} */
451
zend_fopen_wrapper(const char * filename,char ** opened_path TSRMLS_DC)452 static FILE *zend_fopen_wrapper(const char *filename, char **opened_path TSRMLS_DC) /* {{{ */
453 {
454 if (opened_path) {
455 *opened_path = estrdup(filename);
456 }
457 return fopen(filename, "rb");
458 }
459 /* }}} */
460
461 #ifdef ZTS
462 static zend_bool asp_tags_default = 0;
463 static zend_bool short_tags_default = 1;
464 static zend_uint compiler_options_default = ZEND_COMPILE_DEFAULT;
465 #else
466 # define asp_tags_default 0
467 # define short_tags_default 1
468 # define compiler_options_default ZEND_COMPILE_DEFAULT
469 #endif
470
zend_set_default_compile_time_values(TSRMLS_D)471 static void zend_set_default_compile_time_values(TSRMLS_D) /* {{{ */
472 {
473 /* default compile-time values */
474 CG(asp_tags) = asp_tags_default;
475 CG(short_tags) = short_tags_default;
476 CG(compiler_options) = compiler_options_default;
477 }
478 /* }}} */
479
zend_init_exception_op(TSRMLS_D)480 static void zend_init_exception_op(TSRMLS_D) /* {{{ */
481 {
482 memset(EG(exception_op), 0, sizeof(EG(exception_op)));
483 EG(exception_op)[0].opcode = ZEND_HANDLE_EXCEPTION;
484 EG(exception_op)[0].op1_type = IS_UNUSED;
485 EG(exception_op)[0].op2_type = IS_UNUSED;
486 EG(exception_op)[0].result_type = IS_UNUSED;
487 ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op));
488 EG(exception_op)[1].opcode = ZEND_HANDLE_EXCEPTION;
489 EG(exception_op)[1].op1_type = IS_UNUSED;
490 EG(exception_op)[1].op2_type = IS_UNUSED;
491 EG(exception_op)[1].result_type = IS_UNUSED;
492 ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1);
493 EG(exception_op)[2].opcode = ZEND_HANDLE_EXCEPTION;
494 EG(exception_op)[2].op1_type = IS_UNUSED;
495 EG(exception_op)[2].op2_type = IS_UNUSED;
496 EG(exception_op)[2].result_type = IS_UNUSED;
497 ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+2);
498 }
499 /* }}} */
500
501 #ifdef ZTS
compiler_globals_ctor(zend_compiler_globals * compiler_globals TSRMLS_DC)502 static void compiler_globals_ctor(zend_compiler_globals *compiler_globals TSRMLS_DC) /* {{{ */
503 {
504 zend_function tmp_func;
505 zend_class_entry *tmp_class;
506
507 compiler_globals->compiled_filename = NULL;
508
509 compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
510 zend_hash_init_ex(compiler_globals->function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
511 zend_hash_copy(compiler_globals->function_table, global_function_table, NULL, &tmp_func, sizeof(zend_function));
512
513 compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
514 zend_hash_init_ex(compiler_globals->class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
515 zend_hash_copy(compiler_globals->class_table, global_class_table, (copy_ctor_func_t) zend_class_add_ref, &tmp_class, sizeof(zend_class_entry *));
516
517 zend_set_default_compile_time_values(TSRMLS_C);
518
519 CG(interactive) = 0;
520
521 compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable));
522 zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, NULL, 1, 0);
523 zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, NULL, NULL, sizeof(zend_auto_global) /* empty element */);
524
525 compiler_globals->last_static_member = zend_hash_num_elements(compiler_globals->class_table);
526 if (compiler_globals->last_static_member) {
527 compiler_globals->static_members_table = calloc(compiler_globals->last_static_member, sizeof(zval**));
528 } else {
529 compiler_globals->static_members_table = NULL;
530 }
531 compiler_globals->script_encoding_list = NULL;
532 }
533 /* }}} */
534
compiler_globals_dtor(zend_compiler_globals * compiler_globals TSRMLS_DC)535 static void compiler_globals_dtor(zend_compiler_globals *compiler_globals TSRMLS_DC) /* {{{ */
536 {
537 if (compiler_globals->function_table != GLOBAL_FUNCTION_TABLE) {
538 zend_hash_destroy(compiler_globals->function_table);
539 free(compiler_globals->function_table);
540 }
541 if (compiler_globals->class_table != GLOBAL_CLASS_TABLE) {
542 zend_hash_destroy(compiler_globals->class_table);
543 free(compiler_globals->class_table);
544 }
545 if (compiler_globals->auto_globals != GLOBAL_AUTO_GLOBALS_TABLE) {
546 zend_hash_destroy(compiler_globals->auto_globals);
547 free(compiler_globals->auto_globals);
548 }
549 if (compiler_globals->static_members_table) {
550 free(compiler_globals->static_members_table);
551 }
552 if (compiler_globals->script_encoding_list) {
553 pefree(compiler_globals->script_encoding_list, 1);
554 }
555 compiler_globals->last_static_member = 0;
556 }
557 /* }}} */
558
executor_globals_ctor(zend_executor_globals * executor_globals TSRMLS_DC)559 static void executor_globals_ctor(zend_executor_globals *executor_globals TSRMLS_DC) /* {{{ */
560 {
561 zend_startup_constants(TSRMLS_C);
562 zend_copy_constants(EG(zend_constants), GLOBAL_CONSTANTS_TABLE);
563 zend_init_rsrc_plist(TSRMLS_C);
564 zend_init_exception_op(TSRMLS_C);
565 EG(lambda_count) = 0;
566 EG(user_error_handler) = NULL;
567 EG(user_exception_handler) = NULL;
568 EG(in_execution) = 0;
569 EG(in_autoload) = NULL;
570 EG(current_execute_data) = NULL;
571 EG(current_module) = NULL;
572 EG(exit_status) = 0;
573 #if XPFPA_HAVE_CW
574 EG(saved_fpu_cw) = 0;
575 #endif
576 EG(saved_fpu_cw_ptr) = NULL;
577 EG(active) = 0;
578 }
579 /* }}} */
580
executor_globals_dtor(zend_executor_globals * executor_globals TSRMLS_DC)581 static void executor_globals_dtor(zend_executor_globals *executor_globals TSRMLS_DC) /* {{{ */
582 {
583 zend_ini_shutdown(TSRMLS_C);
584 if (&executor_globals->persistent_list != global_persistent_list) {
585 zend_destroy_rsrc_list(&executor_globals->persistent_list TSRMLS_CC);
586 }
587 if (executor_globals->zend_constants != GLOBAL_CONSTANTS_TABLE) {
588 zend_hash_destroy(executor_globals->zend_constants);
589 free(executor_globals->zend_constants);
590 }
591 }
592 /* }}} */
593
zend_new_thread_end_handler(THREAD_T thread_id TSRMLS_DC)594 static void zend_new_thread_end_handler(THREAD_T thread_id TSRMLS_DC) /* {{{ */
595 {
596 if (zend_copy_ini_directives(TSRMLS_C) == SUCCESS) {
597 zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP TSRMLS_CC);
598 }
599 }
600 /* }}} */
601 #endif
602
603 #if defined(__FreeBSD__) || defined(__DragonFly__)
604 /* FreeBSD and DragonFly floating point precision fix */
605 #include <floatingpoint.h>
606 #endif
607
ini_scanner_globals_ctor(zend_ini_scanner_globals * scanner_globals_p TSRMLS_DC)608 static void ini_scanner_globals_ctor(zend_ini_scanner_globals *scanner_globals_p TSRMLS_DC) /* {{{ */
609 {
610 memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
611 }
612 /* }}} */
613
php_scanner_globals_ctor(zend_php_scanner_globals * scanner_globals_p TSRMLS_DC)614 static void php_scanner_globals_ctor(zend_php_scanner_globals *scanner_globals_p TSRMLS_DC) /* {{{ */
615 {
616 memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
617 }
618 /* }}} */
619
620 void zend_init_opcodes_handlers(void);
621
php_auto_globals_create_globals(const char * name,uint name_len TSRMLS_DC)622 static zend_bool php_auto_globals_create_globals(const char *name, uint name_len TSRMLS_DC) /* {{{ */
623 {
624 zval *globals;
625
626 ALLOC_ZVAL(globals);
627 Z_SET_REFCOUNT_P(globals, 1);
628 Z_SET_ISREF_P(globals);
629 Z_TYPE_P(globals) = IS_ARRAY;
630 Z_ARRVAL_P(globals) = &EG(symbol_table);
631 zend_hash_update(&EG(symbol_table), name, name_len + 1, &globals, sizeof(zval *), NULL);
632 return 0;
633 }
634 /* }}} */
635
zend_startup(zend_utility_functions * utility_functions,char ** extensions TSRMLS_DC)636 int zend_startup(zend_utility_functions *utility_functions, char **extensions TSRMLS_DC) /* {{{ */
637 {
638 #ifdef ZTS
639 zend_compiler_globals *compiler_globals;
640 zend_executor_globals *executor_globals;
641 extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
642 extern ZEND_API ts_rsrc_id language_scanner_globals_id;
643 #else
644 extern zend_ini_scanner_globals ini_scanner_globals;
645 extern zend_php_scanner_globals language_scanner_globals;
646 #endif
647
648 start_memory_manager(TSRMLS_C);
649
650 #if defined(__FreeBSD__) || defined(__DragonFly__)
651 /* FreeBSD and DragonFly floating point precision fix */
652 fpsetmask(0);
653 #endif
654
655 zend_startup_strtod();
656 zend_startup_extensions_mechanism();
657
658 /* Set up utility functions and values */
659 zend_error_cb = utility_functions->error_function;
660 zend_printf = utility_functions->printf_function;
661 zend_write = (zend_write_func_t) utility_functions->write_function;
662 zend_fopen = utility_functions->fopen_function;
663 if (!zend_fopen) {
664 zend_fopen = zend_fopen_wrapper;
665 }
666 zend_stream_open_function = utility_functions->stream_open_function;
667 zend_message_dispatcher_p = utility_functions->message_handler;
668 #ifndef ZEND_SIGNALS
669 zend_block_interruptions = utility_functions->block_interruptions;
670 zend_unblock_interruptions = utility_functions->unblock_interruptions;
671 #endif
672 zend_get_configuration_directive_p = utility_functions->get_configuration_directive;
673 zend_ticks_function = utility_functions->ticks_function;
674 zend_on_timeout = utility_functions->on_timeout;
675 zend_vspprintf = utility_functions->vspprintf_function;
676 zend_getenv = utility_functions->getenv_function;
677 zend_resolve_path = utility_functions->resolve_path_function;
678
679 #if HAVE_DTRACE
680 /* build with dtrace support */
681 zend_compile_file = dtrace_compile_file;
682 zend_execute = dtrace_execute;
683 zend_execute_internal = dtrace_execute_internal;
684 #else
685 zend_compile_file = compile_file;
686 zend_execute = execute;
687 zend_execute_internal = NULL;
688 #endif /* HAVE_SYS_SDT_H */
689 zend_compile_string = compile_string;
690 zend_throw_exception_hook = NULL;
691
692 zend_init_opcodes_handlers();
693
694 /* set up version */
695 zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
696 zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO) - 1;
697
698 GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
699 GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
700 GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
701 GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable));
702
703 zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
704 zend_hash_init_ex(GLOBAL_CLASS_TABLE, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
705 zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, NULL, 1, 0);
706 zend_hash_init_ex(GLOBAL_CONSTANTS_TABLE, 20, NULL, ZEND_CONSTANT_DTOR, 1, 0);
707
708 zend_hash_init_ex(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1, 0);
709 zend_init_rsrc_list_dtors();
710
711 /* This zval can be used to initialize allocate zval's to an uninit'ed value */
712 Z_UNSET_ISREF(zval_used_for_init);
713 Z_SET_REFCOUNT(zval_used_for_init, 1);
714 Z_TYPE(zval_used_for_init) = IS_NULL;
715
716 #ifdef ZTS
717 ts_allocate_id(&compiler_globals_id, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
718 ts_allocate_id(&executor_globals_id, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
719 ts_allocate_id(&language_scanner_globals_id, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL);
720 ts_allocate_id(&ini_scanner_globals_id, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL);
721 compiler_globals = ts_resource(compiler_globals_id);
722 executor_globals = ts_resource(executor_globals_id);
723
724 compiler_globals_dtor(compiler_globals TSRMLS_CC);
725 compiler_globals->in_compilation = 0;
726 compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
727 compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
728
729 *compiler_globals->function_table = *GLOBAL_FUNCTION_TABLE;
730 *compiler_globals->class_table = *GLOBAL_CLASS_TABLE;
731 compiler_globals->auto_globals = GLOBAL_AUTO_GLOBALS_TABLE;
732
733 zend_hash_destroy(executor_globals->zend_constants);
734 *executor_globals->zend_constants = *GLOBAL_CONSTANTS_TABLE;
735 #else
736 ini_scanner_globals_ctor(&ini_scanner_globals TSRMLS_CC);
737 php_scanner_globals_ctor(&language_scanner_globals TSRMLS_CC);
738 zend_set_default_compile_time_values(TSRMLS_C);
739 EG(user_error_handler) = NULL;
740 EG(user_exception_handler) = NULL;
741 #endif
742
743 zend_interned_strings_init(TSRMLS_C);
744 zend_startup_builtin_functions(TSRMLS_C);
745 zend_register_standard_constants(TSRMLS_C);
746 zend_register_auto_global("GLOBALS", sizeof("GLOBALS") - 1, 1, php_auto_globals_create_globals TSRMLS_CC);
747
748 #ifndef ZTS
749 zend_init_rsrc_plist(TSRMLS_C);
750 zend_init_exception_op(TSRMLS_C);
751 #endif
752
753 zend_ini_startup(TSRMLS_C);
754
755 #ifdef ZTS
756 tsrm_set_new_thread_end_handler(zend_new_thread_end_handler);
757 #endif
758
759 return SUCCESS;
760 }
761 /* }}} */
762
zend_register_standard_ini_entries(TSRMLS_D)763 void zend_register_standard_ini_entries(TSRMLS_D) /* {{{ */
764 {
765 int module_number = 0;
766
767 REGISTER_INI_ENTRIES();
768 }
769 /* }}} */
770
771 /* Unlink the global (r/o) copies of the class, function and constant tables,
772 * and use a fresh r/w copy for the startup thread
773 */
zend_post_startup(TSRMLS_D)774 void zend_post_startup(TSRMLS_D) /* {{{ */
775 {
776 #ifdef ZTS
777 zend_encoding **script_encoding_list;
778
779 zend_compiler_globals *compiler_globals = ts_resource(compiler_globals_id);
780 zend_executor_globals *executor_globals = ts_resource(executor_globals_id);
781
782 *GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table;
783 *GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
784 *GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants;
785
786 asp_tags_default = CG(asp_tags);
787 short_tags_default = CG(short_tags);
788 compiler_options_default = CG(compiler_options);
789
790 zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
791 free(compiler_globals->function_table);
792 free(compiler_globals->class_table);
793 if ((script_encoding_list = (zend_encoding **)compiler_globals->script_encoding_list)) {
794 compiler_globals_ctor(compiler_globals, tsrm_ls);
795 compiler_globals->script_encoding_list = (const zend_encoding **)script_encoding_list;
796 } else {
797 compiler_globals_ctor(compiler_globals, tsrm_ls);
798 }
799 free(EG(zend_constants));
800 executor_globals_ctor(executor_globals, tsrm_ls);
801 global_persistent_list = &EG(persistent_list);
802 zend_copy_ini_directives(TSRMLS_C);
803 #endif
804 }
805 /* }}} */
806
zend_shutdown(TSRMLS_D)807 void zend_shutdown(TSRMLS_D) /* {{{ */
808 {
809 #ifdef ZEND_SIGNALS
810 zend_signal_shutdown(TSRMLS_C);
811 #endif
812 #ifdef ZEND_WIN32
813 zend_shutdown_timeout_thread();
814 #endif
815 zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
816
817 if (EG(active))
818 {
819 /*
820 * The order of destruction is important here.
821 * See bugs #65463 and 66036.
822 */
823 zend_hash_reverse_apply(GLOBAL_FUNCTION_TABLE, (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC);
824 zend_hash_reverse_apply(GLOBAL_CLASS_TABLE, (apply_func_t) zend_cleanup_user_class_data TSRMLS_CC);
825 zend_cleanup_internal_classes(TSRMLS_C);
826 zend_hash_reverse_apply(GLOBAL_FUNCTION_TABLE, (apply_func_t) clean_non_persistent_function_full TSRMLS_CC);
827 zend_hash_reverse_apply(GLOBAL_CLASS_TABLE, (apply_func_t) clean_non_persistent_class_full TSRMLS_CC);
828 }
829
830 zend_destroy_modules();
831
832 zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
833 zend_hash_destroy(GLOBAL_CLASS_TABLE);
834
835 zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
836 free(GLOBAL_AUTO_GLOBALS_TABLE);
837
838 zend_shutdown_extensions(TSRMLS_C);
839 free(zend_version_info);
840
841 free(GLOBAL_FUNCTION_TABLE);
842 free(GLOBAL_CLASS_TABLE);
843
844 zend_hash_destroy(GLOBAL_CONSTANTS_TABLE);
845 free(GLOBAL_CONSTANTS_TABLE);
846 zend_shutdown_strtod();
847
848 #ifdef ZTS
849 GLOBAL_FUNCTION_TABLE = NULL;
850 GLOBAL_CLASS_TABLE = NULL;
851 GLOBAL_AUTO_GLOBALS_TABLE = NULL;
852 GLOBAL_CONSTANTS_TABLE = NULL;
853 #endif
854 zend_destroy_rsrc_list_dtors();
855
856 zend_interned_strings_dtor(TSRMLS_C);
857 }
858 /* }}} */
859
zend_set_utility_values(zend_utility_values * utility_values)860 void zend_set_utility_values(zend_utility_values *utility_values) /* {{{ */
861 {
862 zend_uv = *utility_values;
863 zend_uv.import_use_extension_length = strlen(zend_uv.import_use_extension);
864 }
865 /* }}} */
866
867 /* this should be compatible with the standard zenderror */
zenderror(const char * error)868 void zenderror(const char *error) /* {{{ */
869 {
870 zend_error(E_PARSE, "%s", error);
871 }
872 /* }}} */
873
BEGIN_EXTERN_C()874 BEGIN_EXTERN_C()
875 ZEND_API void _zend_bailout(char *filename, uint lineno) /* {{{ */
876 {
877 TSRMLS_FETCH();
878
879 if (!EG(bailout)) {
880 zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", filename, lineno);
881 exit(-1);
882 }
883 CG(unclean_shutdown) = 1;
884 CG(active_class_entry) = NULL;
885 CG(in_compilation) = EG(in_execution) = 0;
886 EG(current_execute_data) = NULL;
887 LONGJMP(*EG(bailout), FAILURE);
888 }
889 /* }}} */
END_EXTERN_C()890 END_EXTERN_C()
891
892 void zend_append_version_info(const zend_extension *extension) /* {{{ */
893 {
894 char *new_info;
895 uint new_info_length;
896
897 new_info_length = sizeof(" with v, , by \n")
898 + strlen(extension->name)
899 + strlen(extension->version)
900 + strlen(extension->copyright)
901 + strlen(extension->author);
902
903 new_info = (char *) malloc(new_info_length + 1);
904
905 snprintf(new_info, new_info_length, " with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author);
906
907 zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length + 1);
908 strncat(zend_version_info, new_info, new_info_length);
909 zend_version_info_length += new_info_length;
910 free(new_info);
911 }
912 /* }}} */
913
get_zend_version(void)914 ZEND_API char *get_zend_version(void) /* {{{ */
915 {
916 return zend_version_info;
917 }
918 /* }}} */
919
zend_activate(TSRMLS_D)920 void zend_activate(TSRMLS_D) /* {{{ */
921 {
922 gc_reset(TSRMLS_C);
923 init_compiler(TSRMLS_C);
924 init_executor(TSRMLS_C);
925 startup_scanner(TSRMLS_C);
926 }
927 /* }}} */
928
zend_call_destructors(TSRMLS_D)929 void zend_call_destructors(TSRMLS_D) /* {{{ */
930 {
931 zend_try {
932 shutdown_destructors(TSRMLS_C);
933 } zend_end_try();
934 }
935 /* }}} */
936
zend_deactivate(TSRMLS_D)937 void zend_deactivate(TSRMLS_D) /* {{{ */
938 {
939 /* we're no longer executing anything */
940 EG(opline_ptr) = NULL;
941 EG(active_symbol_table) = NULL;
942
943 zend_try {
944 shutdown_scanner(TSRMLS_C);
945 } zend_end_try();
946
947 /* shutdown_executor() takes care of its own bailout handling */
948 shutdown_executor(TSRMLS_C);
949
950 zend_try {
951 shutdown_compiler(TSRMLS_C);
952 } zend_end_try();
953
954 zend_destroy_rsrc_list(&EG(regular_list) TSRMLS_CC);
955
956 #ifdef ZEND_DEBUG
957 if (GC_G(gc_enabled) && !CG(unclean_shutdown)) {
958 gc_collect_cycles(TSRMLS_C);
959 }
960 #endif
961
962 #if GC_BENCH
963 fprintf(stderr, "GC Statistics\n");
964 fprintf(stderr, "-------------\n");
965 fprintf(stderr, "Runs: %d\n", GC_G(gc_runs));
966 fprintf(stderr, "Collected: %d\n", GC_G(collected));
967 fprintf(stderr, "Root buffer length: %d\n", GC_G(root_buf_length));
968 fprintf(stderr, "Root buffer peak: %d\n\n", GC_G(root_buf_peak));
969 fprintf(stderr, " Possible Remove from Marked\n");
970 fprintf(stderr, " Root Buffered buffer grey\n");
971 fprintf(stderr, " -------- -------- ----------- ------\n");
972 fprintf(stderr, "ZVAL %8d %8d %9d %8d\n", GC_G(zval_possible_root), GC_G(zval_buffered), GC_G(zval_remove_from_buffer), GC_G(zval_marked_grey));
973 fprintf(stderr, "ZOBJ %8d %8d %9d %8d\n", GC_G(zobj_possible_root), GC_G(zobj_buffered), GC_G(zobj_remove_from_buffer), GC_G(zobj_marked_grey));
974 #endif
975
976 zend_try {
977 zend_ini_deactivate(TSRMLS_C);
978 } zend_end_try();
979 }
980 /* }}} */
981
BEGIN_EXTERN_C()982 BEGIN_EXTERN_C()
983 ZEND_API void zend_message_dispatcher(long message, const void *data TSRMLS_DC) /* {{{ */
984 {
985 if (zend_message_dispatcher_p) {
986 zend_message_dispatcher_p(message, data TSRMLS_CC);
987 }
988 }
989 /* }}} */
END_EXTERN_C()990 END_EXTERN_C()
991
992 ZEND_API int zend_get_configuration_directive(const char *name, uint name_length, zval *contents) /* {{{ */
993 {
994 if (zend_get_configuration_directive_p) {
995 return zend_get_configuration_directive_p(name, name_length, contents);
996 } else {
997 return FAILURE;
998 }
999 }
1000 /* }}} */
1001
1002 #define SAVE_STACK(stack) do { \
1003 if (CG(stack).top) { \
1004 memcpy(&stack, &CG(stack), sizeof(zend_stack)); \
1005 CG(stack).top = CG(stack).max = 0; \
1006 CG(stack).elements = NULL; \
1007 } else { \
1008 stack.top = 0; \
1009 } \
1010 } while (0)
1011
1012 #define RESTORE_STACK(stack) do { \
1013 if (stack.top) { \
1014 zend_stack_destroy(&CG(stack)); \
1015 memcpy(&CG(stack), &stack, sizeof(zend_stack)); \
1016 } \
1017 } while (0)
1018
zend_error(int type,const char * format,...)1019 ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
1020 {
1021 va_list args;
1022 va_list usr_copy;
1023 zval ***params;
1024 zval *retval;
1025 zval *z_error_type, *z_error_message, *z_error_filename, *z_error_lineno, *z_context;
1026 const char *error_filename;
1027 uint error_lineno;
1028 zval *orig_user_error_handler;
1029 zend_bool in_compilation;
1030 zend_class_entry *saved_class_entry;
1031 zend_stack bp_stack;
1032 zend_stack function_call_stack;
1033 zend_stack switch_cond_stack;
1034 zend_stack foreach_copy_stack;
1035 zend_stack object_stack;
1036 zend_stack declare_stack;
1037 zend_stack list_stack;
1038 zend_stack context_stack;
1039 TSRMLS_FETCH();
1040
1041 /* Report about uncaught exception in case of fatal errors */
1042 if (EG(exception)) {
1043 switch (type) {
1044 case E_CORE_ERROR:
1045 case E_ERROR:
1046 case E_RECOVERABLE_ERROR:
1047 case E_PARSE:
1048 case E_COMPILE_ERROR:
1049 case E_USER_ERROR:
1050 if (zend_is_executing(TSRMLS_C)) {
1051 error_lineno = zend_get_executed_lineno(TSRMLS_C);
1052 }
1053 zend_exception_error(EG(exception), E_WARNING TSRMLS_CC);
1054 EG(exception) = NULL;
1055 if (zend_is_executing(TSRMLS_C) && EG(opline_ptr)) {
1056 active_opline->lineno = error_lineno;
1057 }
1058 break;
1059 default:
1060 break;
1061 }
1062 }
1063
1064 /* Obtain relevant filename and lineno */
1065 switch (type) {
1066 case E_CORE_ERROR:
1067 case E_CORE_WARNING:
1068 error_filename = NULL;
1069 error_lineno = 0;
1070 break;
1071 case E_PARSE:
1072 case E_COMPILE_ERROR:
1073 case E_COMPILE_WARNING:
1074 case E_ERROR:
1075 case E_NOTICE:
1076 case E_STRICT:
1077 case E_DEPRECATED:
1078 case E_WARNING:
1079 case E_USER_ERROR:
1080 case E_USER_WARNING:
1081 case E_USER_NOTICE:
1082 case E_USER_DEPRECATED:
1083 case E_RECOVERABLE_ERROR:
1084 if (zend_is_compiling(TSRMLS_C)) {
1085 error_filename = zend_get_compiled_filename(TSRMLS_C);
1086 error_lineno = zend_get_compiled_lineno(TSRMLS_C);
1087 } else if (zend_is_executing(TSRMLS_C)) {
1088 error_filename = zend_get_executed_filename(TSRMLS_C);
1089 error_lineno = zend_get_executed_lineno(TSRMLS_C);
1090 } else {
1091 error_filename = NULL;
1092 error_lineno = 0;
1093 }
1094 break;
1095 default:
1096 error_filename = NULL;
1097 error_lineno = 0;
1098 break;
1099 }
1100 if (!error_filename) {
1101 error_filename = "Unknown";
1102 }
1103
1104 #ifdef HAVE_DTRACE
1105 if(DTRACE_ERROR_ENABLED()) {
1106 char *dtrace_error_buffer;
1107 va_start(args, format);
1108 zend_vspprintf(&dtrace_error_buffer, 0, format, args);
1109 DTRACE_ERROR(dtrace_error_buffer, (char *)error_filename, error_lineno);
1110 efree(dtrace_error_buffer);
1111 va_end(args);
1112 }
1113 #endif /* HAVE_DTRACE */
1114
1115 va_start(args, format);
1116
1117 /* if we don't have a user defined error handler */
1118 if (!EG(user_error_handler)
1119 || !(EG(user_error_handler_error_reporting) & type)
1120 || EG(error_handling) != EH_NORMAL) {
1121 zend_error_cb(type, error_filename, error_lineno, format, args);
1122 } else switch (type) {
1123 case E_ERROR:
1124 case E_PARSE:
1125 case E_CORE_ERROR:
1126 case E_CORE_WARNING:
1127 case E_COMPILE_ERROR:
1128 case E_COMPILE_WARNING:
1129 /* The error may not be safe to handle in user-space */
1130 zend_error_cb(type, error_filename, error_lineno, format, args);
1131 break;
1132 default:
1133 /* Handle the error in user space */
1134 ALLOC_INIT_ZVAL(z_error_message);
1135 ALLOC_INIT_ZVAL(z_error_type);
1136 ALLOC_INIT_ZVAL(z_error_filename);
1137 ALLOC_INIT_ZVAL(z_error_lineno);
1138 ALLOC_INIT_ZVAL(z_context);
1139
1140 /* va_copy() is __va_copy() in old gcc versions.
1141 * According to the autoconf manual, using
1142 * memcpy(&dst, &src, sizeof(va_list))
1143 * gives maximum portability. */
1144 #ifndef va_copy
1145 # ifdef __va_copy
1146 # define va_copy(dest, src) __va_copy((dest), (src))
1147 # else
1148 # define va_copy(dest, src) memcpy(&(dest), &(src), sizeof(va_list))
1149 # endif
1150 #endif
1151 va_copy(usr_copy, args);
1152 Z_STRLEN_P(z_error_message) = zend_vspprintf(&Z_STRVAL_P(z_error_message), 0, format, usr_copy);
1153 #ifdef va_copy
1154 va_end(usr_copy);
1155 #endif
1156 Z_TYPE_P(z_error_message) = IS_STRING;
1157
1158 Z_LVAL_P(z_error_type) = type;
1159 Z_TYPE_P(z_error_type) = IS_LONG;
1160
1161 if (error_filename) {
1162 ZVAL_STRING(z_error_filename, error_filename, 1);
1163 }
1164
1165 Z_LVAL_P(z_error_lineno) = error_lineno;
1166 Z_TYPE_P(z_error_lineno) = IS_LONG;
1167
1168 if (!EG(active_symbol_table)) {
1169 zend_rebuild_symbol_table(TSRMLS_C);
1170 }
1171
1172 /* during shutdown the symbol table table can be still null */
1173 if (!EG(active_symbol_table)) {
1174 Z_TYPE_P(z_context) = IS_NULL;
1175 } else {
1176 Z_ARRVAL_P(z_context) = EG(active_symbol_table);
1177 Z_TYPE_P(z_context) = IS_ARRAY;
1178 zval_copy_ctor(z_context);
1179 }
1180
1181 params = (zval ***) emalloc(sizeof(zval **)*5);
1182 params[0] = &z_error_type;
1183 params[1] = &z_error_message;
1184 params[2] = &z_error_filename;
1185 params[3] = &z_error_lineno;
1186 params[4] = &z_context;
1187
1188 orig_user_error_handler = EG(user_error_handler);
1189 EG(user_error_handler) = NULL;
1190
1191 /* User error handler may include() additinal PHP files.
1192 * If an error was generated during comilation PHP will compile
1193 * such scripts recursivly, but some CG() variables may be
1194 * inconsistent. */
1195
1196 in_compilation = CG(in_compilation);
1197 if (in_compilation) {
1198 saved_class_entry = CG(active_class_entry);
1199 CG(active_class_entry) = NULL;
1200 SAVE_STACK(bp_stack);
1201 SAVE_STACK(function_call_stack);
1202 SAVE_STACK(switch_cond_stack);
1203 SAVE_STACK(foreach_copy_stack);
1204 SAVE_STACK(object_stack);
1205 SAVE_STACK(declare_stack);
1206 SAVE_STACK(list_stack);
1207 SAVE_STACK(context_stack);
1208 CG(in_compilation) = 0;
1209 }
1210
1211 if (call_user_function_ex(CG(function_table), NULL, orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) {
1212 if (retval) {
1213 if (Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval) == 0) {
1214 zend_error_cb(type, error_filename, error_lineno, format, args);
1215 }
1216 zval_ptr_dtor(&retval);
1217 }
1218 } else if (!EG(exception)) {
1219 /* The user error handler failed, use built-in error handler */
1220 zend_error_cb(type, error_filename, error_lineno, format, args);
1221 }
1222
1223 if (in_compilation) {
1224 CG(active_class_entry) = saved_class_entry;
1225 RESTORE_STACK(bp_stack);
1226 RESTORE_STACK(function_call_stack);
1227 RESTORE_STACK(switch_cond_stack);
1228 RESTORE_STACK(foreach_copy_stack);
1229 RESTORE_STACK(object_stack);
1230 RESTORE_STACK(declare_stack);
1231 RESTORE_STACK(list_stack);
1232 RESTORE_STACK(context_stack);
1233 CG(in_compilation) = 1;
1234 }
1235
1236 if (!EG(user_error_handler)) {
1237 EG(user_error_handler) = orig_user_error_handler;
1238 }
1239 else {
1240 zval_ptr_dtor(&orig_user_error_handler);
1241 }
1242
1243 efree(params);
1244 zval_ptr_dtor(&z_error_message);
1245 zval_ptr_dtor(&z_error_type);
1246 zval_ptr_dtor(&z_error_filename);
1247 zval_ptr_dtor(&z_error_lineno);
1248 zval_ptr_dtor(&z_context);
1249 break;
1250 }
1251
1252 va_end(args);
1253
1254 if (type == E_PARSE) {
1255 /* eval() errors do not affect exit_status */
1256 if (!(EG(current_execute_data) &&
1257 EG(current_execute_data)->opline &&
1258 EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
1259 EG(current_execute_data)->opline->extended_value == ZEND_EVAL)) {
1260 EG(exit_status) = 255;
1261 }
1262 zend_init_compiler_data_structures(TSRMLS_C);
1263 }
1264 }
1265 /* }}} */
1266
1267 #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)
1268 void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn));
1269 #endif
1270
zend_output_debug_string(zend_bool trigger_break,const char * format,...)1271 ZEND_API void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) /* {{{ */
1272 {
1273 #if ZEND_DEBUG
1274 va_list args;
1275
1276 va_start(args, format);
1277 # ifdef ZEND_WIN32
1278 {
1279 char output_buf[1024];
1280
1281 vsnprintf(output_buf, 1024, format, args);
1282 OutputDebugString(output_buf);
1283 OutputDebugString("\n");
1284 if (trigger_break && IsDebuggerPresent()) {
1285 DebugBreak();
1286 }
1287 }
1288 # else
1289 vfprintf(stderr, format, args);
1290 fprintf(stderr, "\n");
1291 # endif
1292 va_end(args);
1293 #endif
1294 }
1295 /* }}} */
1296
zend_execute_scripts(int type TSRMLS_DC,zval ** retval,int file_count,...)1297 ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) /* {{{ */
1298 {
1299 va_list files;
1300 int i;
1301 zend_file_handle *file_handle;
1302 zend_op_array *orig_op_array = EG(active_op_array);
1303 zval **orig_retval_ptr_ptr = EG(return_value_ptr_ptr);
1304 long orig_interactive = CG(interactive);
1305
1306 va_start(files, file_count);
1307 for (i = 0; i < file_count; i++) {
1308 file_handle = va_arg(files, zend_file_handle *);
1309 if (!file_handle) {
1310 continue;
1311 }
1312
1313 if (orig_interactive) {
1314 if (file_handle->filename[0] != '-' || file_handle->filename[1]) {
1315 CG(interactive) = 0;
1316 } else {
1317 CG(interactive) = 1;
1318 }
1319 }
1320
1321 EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC);
1322 if (file_handle->opened_path) {
1323 int dummy = 1;
1324 zend_hash_add(&EG(included_files), file_handle->opened_path, strlen(file_handle->opened_path) + 1, (void *)&dummy, sizeof(int), NULL);
1325 }
1326 zend_destroy_file_handle(file_handle TSRMLS_CC);
1327 if (EG(active_op_array)) {
1328 EG(return_value_ptr_ptr) = retval ? retval : NULL;
1329 zend_execute(EG(active_op_array) TSRMLS_CC);
1330 zend_exception_restore(TSRMLS_C);
1331 if (EG(exception)) {
1332 if (EG(user_exception_handler)) {
1333 zval *orig_user_exception_handler;
1334 zval **params[1], *retval2, *old_exception;
1335 old_exception = EG(exception);
1336 EG(exception) = NULL;
1337 params[0] = &old_exception;
1338 orig_user_exception_handler = EG(user_exception_handler);
1339 if (call_user_function_ex(CG(function_table), NULL, orig_user_exception_handler, &retval2, 1, params, 1, NULL TSRMLS_CC) == SUCCESS) {
1340 if (retval2 != NULL) {
1341 zval_ptr_dtor(&retval2);
1342 }
1343 if (EG(exception)) {
1344 zval_ptr_dtor(&EG(exception));
1345 EG(exception) = NULL;
1346 }
1347 zval_ptr_dtor(&old_exception);
1348 } else {
1349 EG(exception) = old_exception;
1350 zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
1351 }
1352 } else {
1353 zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
1354 }
1355 }
1356 destroy_op_array(EG(active_op_array) TSRMLS_CC);
1357 efree(EG(active_op_array));
1358 } else if (type==ZEND_REQUIRE) {
1359 va_end(files);
1360 EG(active_op_array) = orig_op_array;
1361 EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
1362 CG(interactive) = orig_interactive;
1363 return FAILURE;
1364 }
1365 }
1366 va_end(files);
1367 EG(active_op_array) = orig_op_array;
1368 EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
1369 CG(interactive) = orig_interactive;
1370
1371 return SUCCESS;
1372 }
1373 /* }}} */
1374
1375 #define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%d) : %s"
1376
zend_make_compiled_string_description(const char * name TSRMLS_DC)1377 ZEND_API char *zend_make_compiled_string_description(const char *name TSRMLS_DC) /* {{{ */
1378 {
1379 const char *cur_filename;
1380 int cur_lineno;
1381 char *compiled_string_description;
1382
1383 if (zend_is_compiling(TSRMLS_C)) {
1384 cur_filename = zend_get_compiled_filename(TSRMLS_C);
1385 cur_lineno = zend_get_compiled_lineno(TSRMLS_C);
1386 } else if (zend_is_executing(TSRMLS_C)) {
1387 cur_filename = zend_get_executed_filename(TSRMLS_C);
1388 cur_lineno = zend_get_executed_lineno(TSRMLS_C);
1389 } else {
1390 cur_filename = "Unknown";
1391 cur_lineno = 0;
1392 }
1393
1394 zend_spprintf(&compiled_string_description, 0, COMPILED_STRING_DESCRIPTION_FORMAT, cur_filename, cur_lineno, name);
1395 return compiled_string_description;
1396 }
1397 /* }}} */
1398
free_estring(char ** str_p)1399 void free_estring(char **str_p) /* {{{ */
1400 {
1401 efree(*str_p);
1402 }
1403 /* }}} */
1404
1405 /*
1406 * Local variables:
1407 * tab-width: 4
1408 * c-basic-offset: 4
1409 * indent-tabs-mode: t
1410 * End:
1411 */
1412