xref: /PHP-5.4/Zend/zend.c (revision 437612f6)
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