xref: /PHP-7.2/main/main.c (revision 3164186d)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2018 The PHP Group                                |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP 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.php.net/license/3_01.txt                                  |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Authors: Andi Gutmans <andi@zend.com>                                |
16    |          Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
17    |          Zeev Suraski <zeev@zend.com>                                |
18    +----------------------------------------------------------------------+
19 */
20 
21 /* $Id$ */
22 
23 /* {{{ includes
24  */
25 
26 #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
27 
28 #include "php.h"
29 #include <stdio.h>
30 #include <fcntl.h>
31 #ifdef PHP_WIN32
32 #include "win32/time.h"
33 #include "win32/signal.h"
34 #include "win32/php_win32_globals.h"
35 #include "win32/winutil.h"
36 #include <process.h>
37 #endif
38 #if HAVE_SYS_TIME_H
39 #include <sys/time.h>
40 #endif
41 #if HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 #if HAVE_SIGNAL_H
45 #include <signal.h>
46 #endif
47 #if HAVE_SETLOCALE
48 #include <locale.h>
49 #endif
50 #include "zend.h"
51 #include "zend_types.h"
52 #include "zend_extensions.h"
53 #include "php_ini.h"
54 #include "php_globals.h"
55 #include "php_main.h"
56 #include "fopen_wrappers.h"
57 #include "ext/standard/php_standard.h"
58 #include "ext/standard/php_string.h"
59 #include "ext/date/php_date.h"
60 #include "php_variables.h"
61 #include "ext/standard/credits.h"
62 #ifdef PHP_WIN32
63 #include <io.h>
64 #include "win32/php_registry.h"
65 #include "ext/standard/flock_compat.h"
66 #endif
67 #include "php_syslog.h"
68 #include "Zend/zend_exceptions.h"
69 
70 #if PHP_SIGCHILD
71 #include <sys/types.h>
72 #include <sys/wait.h>
73 #endif
74 
75 #include "zend_compile.h"
76 #include "zend_execute.h"
77 #include "zend_highlight.h"
78 #include "zend_extensions.h"
79 #include "zend_ini.h"
80 #include "zend_dtrace.h"
81 
82 #include "php_content_types.h"
83 #include "php_ticks.h"
84 #include "php_streams.h"
85 #include "php_open_temporary_file.h"
86 
87 #include "SAPI.h"
88 #include "rfc1867.h"
89 
90 #include "ext/standard/html_tables.h"
91 
92 #if HAVE_MMAP || defined(PHP_WIN32)
93 # if HAVE_UNISTD_H
94 #  include <unistd.h>
95 #  if defined(_SC_PAGESIZE)
96 #    define REAL_PAGE_SIZE sysconf(_SC_PAGESIZE);
97 #  elif defined(_SC_PAGE_SIZE)
98 #    define REAL_PAGE_SIZE sysconf(_SC_PAGE_SIZE);
99 #  endif
100 # endif
101 # if HAVE_SYS_MMAN_H
102 #  include <sys/mman.h>
103 # endif
104 # ifndef REAL_PAGE_SIZE
105 #  ifdef PAGE_SIZE
106 #   define REAL_PAGE_SIZE PAGE_SIZE
107 #  else
108 #   define REAL_PAGE_SIZE 4096
109 #  endif
110 # endif
111 #endif
112 /* }}} */
113 
114 PHPAPI int (*php_register_internal_extensions_func)(void) = php_register_internal_extensions;
115 
116 #ifndef ZTS
117 php_core_globals core_globals;
118 #else
119 PHPAPI int core_globals_id;
120 #endif
121 
122 #define SAFE_FILENAME(f) ((f)?(f):"-")
123 
get_safe_charset_hint(void)124 static char *get_safe_charset_hint(void) {
125 	ZEND_TLS char *lastHint = NULL;
126 	ZEND_TLS char *lastCodeset = NULL;
127 	char *hint = SG(default_charset);
128 	size_t len = strlen(hint);
129 	size_t i = 0;
130 
131 	if (lastHint == SG(default_charset)) {
132 		return lastCodeset;
133 	}
134 
135 	lastHint = hint;
136 	lastCodeset = NULL;
137 
138 	for (i = 0; i < sizeof(charset_map)/sizeof(charset_map[0]); i++) {
139 		if (len == charset_map[i].codeset_len
140 			&& zend_binary_strcasecmp(hint, len, charset_map[i].codeset, len) == 0) {
141 			lastCodeset = (char*)charset_map[i].codeset;
142 			break;
143 		}
144 	}
145 
146 	return lastCodeset;
147 }
148 
149 /* {{{ PHP_INI_MH
150  */
PHP_INI_MH(OnSetPrecision)151 static PHP_INI_MH(OnSetPrecision)
152 {
153 	zend_long i;
154 
155 	ZEND_ATOL(i, ZSTR_VAL(new_value));
156 	if (i >= -1) {
157 		EG(precision) = i;
158 		return SUCCESS;
159 	} else {
160 		return FAILURE;
161 	}
162 }
163 /* }}} */
164 
165 /* {{{ PHP_INI_MH
166  */
PHP_INI_MH(OnSetSerializePrecision)167 static PHP_INI_MH(OnSetSerializePrecision)
168 {
169 	zend_long i;
170 
171 	ZEND_ATOL(i, ZSTR_VAL(new_value));
172 	if (i >= -1) {
173 		PG(serialize_precision) = i;
174 		return SUCCESS;
175 	} else {
176 		return FAILURE;
177 	}
178 }
179 /* }}} */
180 
181 
182 /* {{{ PHP_INI_MH
183  */
PHP_INI_MH(OnChangeMemoryLimit)184 static PHP_INI_MH(OnChangeMemoryLimit)
185 {
186 	if (new_value) {
187 		PG(memory_limit) = zend_atol(ZSTR_VAL(new_value), (int)ZSTR_LEN(new_value));
188 	} else {
189 		PG(memory_limit) = 1<<30;		/* effectively, no limit */
190 	}
191 	return zend_set_memory_limit(PG(memory_limit));
192 }
193 /* }}} */
194 
195 
196 /* {{{ php_disable_functions
197  */
php_disable_functions(void)198 static void php_disable_functions(void)
199 {
200 	char *s = NULL, *e;
201 
202 	if (!*(INI_STR("disable_functions"))) {
203 		return;
204 	}
205 
206 	e = PG(disable_functions) = strdup(INI_STR("disable_functions"));
207 	if (e == NULL) {
208 		return;
209 	}
210 	while (*e) {
211 		switch (*e) {
212 			case ' ':
213 			case ',':
214 				if (s) {
215 					*e = '\0';
216 					zend_disable_function(s, e-s);
217 					s = NULL;
218 				}
219 				break;
220 			default:
221 				if (!s) {
222 					s = e;
223 				}
224 				break;
225 		}
226 		e++;
227 	}
228 	if (s) {
229 		zend_disable_function(s, e-s);
230 	}
231 }
232 /* }}} */
233 
234 /* {{{ php_disable_classes
235  */
php_disable_classes(void)236 static void php_disable_classes(void)
237 {
238 	char *s = NULL, *e;
239 
240 	if (!*(INI_STR("disable_classes"))) {
241 		return;
242 	}
243 
244 	e = PG(disable_classes) = strdup(INI_STR("disable_classes"));
245 
246 	while (*e) {
247 		switch (*e) {
248 			case ' ':
249 			case ',':
250 				if (s) {
251 					*e = '\0';
252 					zend_disable_class(s, e-s);
253 					s = NULL;
254 				}
255 				break;
256 			default:
257 				if (!s) {
258 					s = e;
259 				}
260 				break;
261 		}
262 		e++;
263 	}
264 	if (s) {
265 		zend_disable_class(s, e-s);
266 	}
267 }
268 /* }}} */
269 
270 /* {{{ php_binary_init
271  */
php_binary_init(void)272 static void php_binary_init(void)
273 {
274 	char *binary_location = NULL;
275 #ifdef PHP_WIN32
276 	binary_location = (char *)malloc(MAXPATHLEN);
277 	if (binary_location && GetModuleFileName(0, binary_location, MAXPATHLEN) == 0) {
278 		free(binary_location);
279 		PG(php_binary) = NULL;
280 	}
281 #else
282 	if (sapi_module.executable_location) {
283 		binary_location = (char *)malloc(MAXPATHLEN);
284 		if (binary_location && !strchr(sapi_module.executable_location, '/')) {
285 			char *envpath, *path;
286 			int found = 0;
287 
288 			if ((envpath = getenv("PATH")) != NULL) {
289 				char *search_dir, search_path[MAXPATHLEN];
290 				char *last = NULL;
291 				zend_stat_t s;
292 
293 				path = estrdup(envpath);
294 				search_dir = php_strtok_r(path, ":", &last);
295 
296 				while (search_dir) {
297 					snprintf(search_path, MAXPATHLEN, "%s/%s", search_dir, sapi_module.executable_location);
298 					if (VCWD_REALPATH(search_path, binary_location) && !VCWD_ACCESS(binary_location, X_OK) && VCWD_STAT(binary_location, &s) == 0 && S_ISREG(s.st_mode)) {
299 						found = 1;
300 						break;
301 					}
302 					search_dir = php_strtok_r(NULL, ":", &last);
303 				}
304 				efree(path);
305 			}
306 			if (!found) {
307 				free(binary_location);
308 				binary_location = NULL;
309 			}
310 		} else if (!VCWD_REALPATH(sapi_module.executable_location, binary_location) || VCWD_ACCESS(binary_location, X_OK)) {
311 			free(binary_location);
312 			binary_location = NULL;
313 		}
314 	}
315 #endif
316 	PG(php_binary) = binary_location;
317 }
318 /* }}} */
319 
320 /* {{{ PHP_INI_MH
321  */
PHP_INI_MH(OnUpdateTimeout)322 static PHP_INI_MH(OnUpdateTimeout)
323 {
324 	if (stage==PHP_INI_STAGE_STARTUP) {
325 		/* Don't set a timeout on startup, only per-request */
326 		ZEND_ATOL(EG(timeout_seconds), ZSTR_VAL(new_value));
327 		return SUCCESS;
328 	}
329 	zend_unset_timeout();
330 	ZEND_ATOL(EG(timeout_seconds), ZSTR_VAL(new_value));
331 	zend_set_timeout(EG(timeout_seconds), 0);
332 	return SUCCESS;
333 }
334 /* }}} */
335 
336 /* {{{ php_get_display_errors_mode() helper function
337  */
php_get_display_errors_mode(char * value,int value_length)338 static int php_get_display_errors_mode(char *value, int value_length)
339 {
340 	int mode;
341 
342 	if (!value) {
343 		return PHP_DISPLAY_ERRORS_STDOUT;
344 	}
345 
346 	if (value_length == 2 && !strcasecmp("on", value)) {
347 		mode = PHP_DISPLAY_ERRORS_STDOUT;
348 	} else if (value_length == 3 && !strcasecmp("yes", value)) {
349 		mode = PHP_DISPLAY_ERRORS_STDOUT;
350 	} else if (value_length == 4 && !strcasecmp("true", value)) {
351 		mode = PHP_DISPLAY_ERRORS_STDOUT;
352 	} else if (value_length == 6 && !strcasecmp(value, "stderr")) {
353 		mode = PHP_DISPLAY_ERRORS_STDERR;
354 	} else if (value_length == 6 && !strcasecmp(value, "stdout")) {
355 		mode = PHP_DISPLAY_ERRORS_STDOUT;
356 	} else {
357 		ZEND_ATOL(mode, value);
358 		if (mode && mode != PHP_DISPLAY_ERRORS_STDOUT && mode != PHP_DISPLAY_ERRORS_STDERR) {
359 			mode = PHP_DISPLAY_ERRORS_STDOUT;
360 		}
361 	}
362 
363 	return mode;
364 }
365 /* }}} */
366 
367 /* {{{ PHP_INI_MH
368  */
PHP_INI_MH(OnUpdateDisplayErrors)369 static PHP_INI_MH(OnUpdateDisplayErrors)
370 {
371 	PG(display_errors) = (zend_bool) php_get_display_errors_mode(ZSTR_VAL(new_value), (int)ZSTR_LEN(new_value));
372 
373 	return SUCCESS;
374 }
375 /* }}} */
376 
377 /* {{{ PHP_INI_DISP
378  */
PHP_INI_DISP(display_errors_mode)379 static PHP_INI_DISP(display_errors_mode)
380 {
381 	int mode, tmp_value_length, cgi_or_cli;
382 	char *tmp_value;
383 
384 	if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
385 		tmp_value = (ini_entry->orig_value ? ZSTR_VAL(ini_entry->orig_value) : NULL );
386 		tmp_value_length = (int)(ini_entry->orig_value? ZSTR_LEN(ini_entry->orig_value) : 0);
387 	} else if (ini_entry->value) {
388 		tmp_value = ZSTR_VAL(ini_entry->value);
389 		tmp_value_length = (int)ZSTR_LEN(ini_entry->value);
390 	} else {
391 		tmp_value = NULL;
392 		tmp_value_length = 0;
393 	}
394 
395 	mode = php_get_display_errors_mode(tmp_value, tmp_value_length);
396 
397 	/* Display 'On' for other SAPIs instead of STDOUT or STDERR */
398 	cgi_or_cli = (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "cgi") || !strcmp(sapi_module.name, "phpdbg"));
399 
400 	switch (mode) {
401 		case PHP_DISPLAY_ERRORS_STDERR:
402 			if (cgi_or_cli ) {
403 				PUTS("STDERR");
404 			} else {
405 				PUTS("On");
406 			}
407 			break;
408 
409 		case PHP_DISPLAY_ERRORS_STDOUT:
410 			if (cgi_or_cli ) {
411 				PUTS("STDOUT");
412 			} else {
413 				PUTS("On");
414 			}
415 			break;
416 
417 		default:
418 			PUTS("Off");
419 			break;
420 	}
421 }
422 /* }}} */
423 
424 /* {{{ PHP_INI_MH
425  */
PHP_INI_MH(OnUpdateDefaultCharset)426 static PHP_INI_MH(OnUpdateDefaultCharset)
427 {
428 	if (new_value) {
429 		OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
430 #ifdef PHP_WIN32
431 		php_win32_cp_do_update(ZSTR_VAL(new_value));
432 #endif
433 	}
434 	return SUCCESS;
435 }
436 /* }}} */
437 
438 /* {{{ PHP_INI_MH
439  */
PHP_INI_MH(OnUpdateInternalEncoding)440 static PHP_INI_MH(OnUpdateInternalEncoding)
441 {
442 	if (new_value) {
443 		OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
444 #ifdef PHP_WIN32
445 		php_win32_cp_do_update(ZSTR_VAL(new_value));
446 #endif
447 	}
448 	return SUCCESS;
449 }
450 /* }}} */
451 
452 /* {{{ PHP_INI_MH
453  */
PHP_INI_MH(OnUpdateInputEncoding)454 static PHP_INI_MH(OnUpdateInputEncoding)
455 {
456 	if (new_value) {
457 		OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
458 #ifdef PHP_WIN32
459 		php_win32_cp_do_update(NULL);
460 #endif
461 	}
462 	return SUCCESS;
463 }
464 /* }}} */
465 
466 /* {{{ PHP_INI_MH
467  */
PHP_INI_MH(OnUpdateOutputEncoding)468 static PHP_INI_MH(OnUpdateOutputEncoding)
469 {
470 	if (new_value) {
471 		OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
472 #ifdef PHP_WIN32
473 		php_win32_cp_do_update(NULL);
474 #endif
475 	}
476 	return SUCCESS;
477 }
478 /* }}} */
479 
480 /* {{{ PHP_INI_MH
481  */
PHP_INI_MH(OnUpdateErrorLog)482 static PHP_INI_MH(OnUpdateErrorLog)
483 {
484 	/* Only do the safemode/open_basedir check at runtime */
485 	if ((stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) && new_value && strcmp(ZSTR_VAL(new_value), "syslog")) {
486 		if (PG(open_basedir) && php_check_open_basedir(ZSTR_VAL(new_value))) {
487 			return FAILURE;
488 		}
489 	}
490 	OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
491 	return SUCCESS;
492 }
493 /* }}} */
494 
495 /* {{{ PHP_INI_MH
496  */
PHP_INI_MH(OnUpdateMailLog)497 static PHP_INI_MH(OnUpdateMailLog)
498 {
499 	/* Only do the safemode/open_basedir check at runtime */
500 	if ((stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) && new_value) {
501 		if (PG(open_basedir) && php_check_open_basedir(ZSTR_VAL(new_value))) {
502 			return FAILURE;
503 		}
504 	}
505 	OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
506 	return SUCCESS;
507 }
508 /* }}} */
509 
510 /* {{{ PHP_INI_MH
511  */
PHP_INI_MH(OnChangeMailForceExtra)512 static PHP_INI_MH(OnChangeMailForceExtra)
513 {
514 	/* Don't allow changing it in htaccess */
515 	if (stage == PHP_INI_STAGE_HTACCESS) {
516 			return FAILURE;
517 	}
518 	return SUCCESS;
519 }
520 /* }}} */
521 
522 /* defined in browscap.c */
523 PHP_INI_MH(OnChangeBrowscap);
524 
525 
526 /* Need to be read from the environment (?):
527  * PHP_AUTO_PREPEND_FILE
528  * PHP_AUTO_APPEND_FILE
529  * PHP_DOCUMENT_ROOT
530  * PHP_USER_DIR
531  * PHP_INCLUDE_PATH
532  */
533 
534  /* Windows use the internal mail */
535 #if defined(PHP_WIN32)
536 # define DEFAULT_SENDMAIL_PATH NULL
537 #elif defined(PHP_PROG_SENDMAIL)
538 # define DEFAULT_SENDMAIL_PATH PHP_PROG_SENDMAIL " -t -i "
539 #else
540 # define DEFAULT_SENDMAIL_PATH "/usr/sbin/sendmail -t -i"
541 #endif
542 
543 /* {{{ PHP_INI
544  */
545 PHP_INI_BEGIN()
546 	PHP_INI_ENTRY_EX("highlight.comment",		HL_COMMENT_COLOR,	PHP_INI_ALL,	NULL,			php_ini_color_displayer_cb)
547 	PHP_INI_ENTRY_EX("highlight.default",		HL_DEFAULT_COLOR,	PHP_INI_ALL,	NULL,			php_ini_color_displayer_cb)
548 	PHP_INI_ENTRY_EX("highlight.html",			HL_HTML_COLOR,		PHP_INI_ALL,	NULL,			php_ini_color_displayer_cb)
549 	PHP_INI_ENTRY_EX("highlight.keyword",		HL_KEYWORD_COLOR,	PHP_INI_ALL,	NULL,			php_ini_color_displayer_cb)
550 	PHP_INI_ENTRY_EX("highlight.string",		HL_STRING_COLOR,	PHP_INI_ALL,	NULL,			php_ini_color_displayer_cb)
551 
552 	STD_PHP_INI_ENTRY_EX("display_errors",		"1",		PHP_INI_ALL,		OnUpdateDisplayErrors,	display_errors,			php_core_globals,	core_globals, display_errors_mode)
553 	STD_PHP_INI_BOOLEAN("display_startup_errors",	"0",	PHP_INI_ALL,		OnUpdateBool,			display_startup_errors,	php_core_globals,	core_globals)
554 	STD_PHP_INI_BOOLEAN("enable_dl",			"1",		PHP_INI_SYSTEM,		OnUpdateBool,			enable_dl,				php_core_globals,	core_globals)
555 	STD_PHP_INI_BOOLEAN("expose_php",			"1",		PHP_INI_SYSTEM,		OnUpdateBool,			expose_php,				php_core_globals,	core_globals)
556 	STD_PHP_INI_ENTRY("docref_root", 			"", 		PHP_INI_ALL,		OnUpdateString,			docref_root,			php_core_globals,	core_globals)
557 	STD_PHP_INI_ENTRY("docref_ext",				"",			PHP_INI_ALL,		OnUpdateString,			docref_ext,				php_core_globals,	core_globals)
558 	STD_PHP_INI_BOOLEAN("html_errors",			"1",		PHP_INI_ALL,		OnUpdateBool,			html_errors,			php_core_globals,	core_globals)
559 	STD_PHP_INI_BOOLEAN("xmlrpc_errors",		"0",		PHP_INI_SYSTEM,		OnUpdateBool,			xmlrpc_errors,			php_core_globals,	core_globals)
560 	STD_PHP_INI_ENTRY("xmlrpc_error_number",	"0",		PHP_INI_ALL,		OnUpdateLong,			xmlrpc_error_number,	php_core_globals,	core_globals)
561 	STD_PHP_INI_ENTRY("max_input_time",			"-1",	PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLong,			max_input_time,	php_core_globals,	core_globals)
562 	STD_PHP_INI_BOOLEAN("ignore_user_abort",	"0",		PHP_INI_ALL,		OnUpdateBool,			ignore_user_abort,		php_core_globals,	core_globals)
563 	STD_PHP_INI_BOOLEAN("implicit_flush",		"0",		PHP_INI_ALL,		OnUpdateBool,			implicit_flush,			php_core_globals,	core_globals)
564 	STD_PHP_INI_BOOLEAN("log_errors",			"0",		PHP_INI_ALL,		OnUpdateBool,			log_errors,				php_core_globals,	core_globals)
565 	STD_PHP_INI_ENTRY("log_errors_max_len",	 "1024",		PHP_INI_ALL,		OnUpdateLong,			log_errors_max_len,		php_core_globals,	core_globals)
566 	STD_PHP_INI_BOOLEAN("ignore_repeated_errors",	"0",	PHP_INI_ALL,		OnUpdateBool,			ignore_repeated_errors,	php_core_globals,	core_globals)
567 	STD_PHP_INI_BOOLEAN("ignore_repeated_source",	"0",	PHP_INI_ALL,		OnUpdateBool,			ignore_repeated_source,	php_core_globals,	core_globals)
568 	STD_PHP_INI_BOOLEAN("report_memleaks",		"1",		PHP_INI_ALL,		OnUpdateBool,			report_memleaks,		php_core_globals,	core_globals)
569 	STD_PHP_INI_BOOLEAN("report_zend_debug",	"1",		PHP_INI_ALL,		OnUpdateBool,			report_zend_debug,		php_core_globals,	core_globals)
570 	STD_PHP_INI_ENTRY("output_buffering",		"0",		PHP_INI_PERDIR|PHP_INI_SYSTEM,	OnUpdateLong,	output_buffering,		php_core_globals,	core_globals)
571 	STD_PHP_INI_ENTRY("output_handler",			NULL,		PHP_INI_PERDIR|PHP_INI_SYSTEM,	OnUpdateString,	output_handler,		php_core_globals,	core_globals)
572 	STD_PHP_INI_BOOLEAN("register_argc_argv",	"1",		PHP_INI_PERDIR|PHP_INI_SYSTEM,	OnUpdateBool,	register_argc_argv,		php_core_globals,	core_globals)
573 	STD_PHP_INI_BOOLEAN("auto_globals_jit",		"1",		PHP_INI_PERDIR|PHP_INI_SYSTEM,	OnUpdateBool,	auto_globals_jit,	php_core_globals,	core_globals)
574 	STD_PHP_INI_BOOLEAN("short_open_tag",	DEFAULT_SHORT_OPEN_TAG,	PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateBool,			short_tags,				zend_compiler_globals,	compiler_globals)
575 	STD_PHP_INI_BOOLEAN("track_errors",			"0",		PHP_INI_ALL,		OnUpdateBool,			track_errors,			php_core_globals,	core_globals)
576 
577 	STD_PHP_INI_ENTRY("unserialize_callback_func",	NULL,	PHP_INI_ALL,		OnUpdateString,			unserialize_callback_func,	php_core_globals,	core_globals)
578 	STD_PHP_INI_ENTRY("serialize_precision",	"-1",	PHP_INI_ALL,		OnSetSerializePrecision,			serialize_precision,	php_core_globals,	core_globals)
579 	STD_PHP_INI_ENTRY("arg_separator.output",	"&",		PHP_INI_ALL,		OnUpdateStringUnempty,	arg_separator.output,	php_core_globals,	core_globals)
580 	STD_PHP_INI_ENTRY("arg_separator.input",	"&",		PHP_INI_SYSTEM|PHP_INI_PERDIR,	OnUpdateStringUnempty,	arg_separator.input,	php_core_globals,	core_globals)
581 
582 	STD_PHP_INI_ENTRY("auto_append_file",		NULL,		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateString,			auto_append_file,		php_core_globals,	core_globals)
583 	STD_PHP_INI_ENTRY("auto_prepend_file",		NULL,		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateString,			auto_prepend_file,		php_core_globals,	core_globals)
584 	STD_PHP_INI_ENTRY("doc_root",				NULL,		PHP_INI_SYSTEM,		OnUpdateStringUnempty,	doc_root,				php_core_globals,	core_globals)
585 	STD_PHP_INI_ENTRY("default_charset",		PHP_DEFAULT_CHARSET,	PHP_INI_ALL,	OnUpdateDefaultCharset,			default_charset,		sapi_globals_struct, sapi_globals)
586 	STD_PHP_INI_ENTRY("default_mimetype",		SAPI_DEFAULT_MIMETYPE,	PHP_INI_ALL,	OnUpdateString,			default_mimetype,		sapi_globals_struct, sapi_globals)
587 	STD_PHP_INI_ENTRY("internal_encoding",		NULL,			PHP_INI_ALL,	OnUpdateInternalEncoding,	internal_encoding,	php_core_globals, core_globals)
588 	STD_PHP_INI_ENTRY("input_encoding",			NULL,			PHP_INI_ALL,	OnUpdateInputEncoding,				input_encoding,		php_core_globals, core_globals)
589 	STD_PHP_INI_ENTRY("output_encoding",		NULL,			PHP_INI_ALL,	OnUpdateOutputEncoding,				output_encoding,	php_core_globals, core_globals)
590 	STD_PHP_INI_ENTRY("error_log",				NULL,		PHP_INI_ALL,		OnUpdateErrorLog,			error_log,				php_core_globals,	core_globals)
591 	STD_PHP_INI_ENTRY("extension_dir",			PHP_EXTENSION_DIR,		PHP_INI_SYSTEM,		OnUpdateStringUnempty,	extension_dir,			php_core_globals,	core_globals)
592 	STD_PHP_INI_ENTRY("sys_temp_dir",			NULL,		PHP_INI_SYSTEM,		OnUpdateStringUnempty,	sys_temp_dir,			php_core_globals,	core_globals)
593 	STD_PHP_INI_ENTRY("include_path",			PHP_INCLUDE_PATH,		PHP_INI_ALL,		OnUpdateStringUnempty,	include_path,			php_core_globals,	core_globals)
594 	PHP_INI_ENTRY("max_execution_time",			"30",		PHP_INI_ALL,			OnUpdateTimeout)
595 	STD_PHP_INI_ENTRY("open_basedir",			NULL,		PHP_INI_ALL,		OnUpdateBaseDir,			open_basedir,			php_core_globals,	core_globals)
596 
597 	STD_PHP_INI_BOOLEAN("file_uploads",			"1",		PHP_INI_SYSTEM,		OnUpdateBool,			file_uploads,			php_core_globals,	core_globals)
598 	STD_PHP_INI_ENTRY("upload_max_filesize",	"2M",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLong,			upload_max_filesize,	php_core_globals,	core_globals)
599 	STD_PHP_INI_ENTRY("post_max_size",			"8M",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLong,			post_max_size,			sapi_globals_struct,sapi_globals)
600 	STD_PHP_INI_ENTRY("upload_tmp_dir",			NULL,		PHP_INI_SYSTEM,		OnUpdateStringUnempty,	upload_tmp_dir,			php_core_globals,	core_globals)
601 	STD_PHP_INI_ENTRY("max_input_nesting_level", "64",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLongGEZero,	max_input_nesting_level,			php_core_globals,	core_globals)
602 	STD_PHP_INI_ENTRY("max_input_vars",			"1000",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLongGEZero,	max_input_vars,						php_core_globals,	core_globals)
603 
604 	STD_PHP_INI_ENTRY("user_dir",				NULL,		PHP_INI_SYSTEM,		OnUpdateString,			user_dir,				php_core_globals,	core_globals)
605 	STD_PHP_INI_ENTRY("variables_order",		"EGPCS",	PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateStringUnempty,	variables_order,		php_core_globals,	core_globals)
606 	STD_PHP_INI_ENTRY("request_order",			NULL,		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateString,	request_order,		php_core_globals,	core_globals)
607 
608 	STD_PHP_INI_ENTRY("error_append_string",	NULL,		PHP_INI_ALL,		OnUpdateString,			error_append_string,	php_core_globals,	core_globals)
609 	STD_PHP_INI_ENTRY("error_prepend_string",	NULL,		PHP_INI_ALL,		OnUpdateString,			error_prepend_string,	php_core_globals,	core_globals)
610 
611 	PHP_INI_ENTRY("SMTP",						"localhost",PHP_INI_ALL,		NULL)
612 	PHP_INI_ENTRY("smtp_port",					"25",		PHP_INI_ALL,		NULL)
613 	STD_PHP_INI_BOOLEAN("mail.add_x_header",			"0",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateBool,			mail_x_header,			php_core_globals,	core_globals)
614 	STD_PHP_INI_ENTRY("mail.log",					NULL,		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateMailLog,			mail_log,			php_core_globals,	core_globals)
615 	PHP_INI_ENTRY("browscap",					NULL,		PHP_INI_SYSTEM,		OnChangeBrowscap)
616 	PHP_INI_ENTRY("memory_limit",				"128M",		PHP_INI_ALL,		OnChangeMemoryLimit)
617 	PHP_INI_ENTRY("precision",					"14",		PHP_INI_ALL,		OnSetPrecision)
618 	PHP_INI_ENTRY("sendmail_from",				NULL,		PHP_INI_ALL,		NULL)
619 	PHP_INI_ENTRY("sendmail_path",	DEFAULT_SENDMAIL_PATH,	PHP_INI_SYSTEM,		NULL)
620 	PHP_INI_ENTRY("mail.force_extra_parameters",NULL,		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnChangeMailForceExtra)
621 	PHP_INI_ENTRY("disable_functions",			"",			PHP_INI_SYSTEM,		NULL)
622 	PHP_INI_ENTRY("disable_classes",			"",			PHP_INI_SYSTEM,		NULL)
623 	PHP_INI_ENTRY("max_file_uploads",			"20",			PHP_INI_SYSTEM|PHP_INI_PERDIR,		NULL)
624 
625 	STD_PHP_INI_BOOLEAN("allow_url_fopen",		"1",		PHP_INI_SYSTEM,		OnUpdateBool,		allow_url_fopen,		php_core_globals,		core_globals)
626 	STD_PHP_INI_BOOLEAN("allow_url_include",	"0",		PHP_INI_SYSTEM,		OnUpdateBool,		allow_url_include,		php_core_globals,		core_globals)
627 	STD_PHP_INI_BOOLEAN("enable_post_data_reading",	"1",	PHP_INI_SYSTEM|PHP_INI_PERDIR,	OnUpdateBool,	enable_post_data_reading,	php_core_globals,	core_globals)
628 
629 	STD_PHP_INI_ENTRY("realpath_cache_size",	"4096K",	PHP_INI_SYSTEM,		OnUpdateLong,	realpath_cache_size_limit,	virtual_cwd_globals,	cwd_globals)
630 	STD_PHP_INI_ENTRY("realpath_cache_ttl",		"120",		PHP_INI_SYSTEM,		OnUpdateLong,	realpath_cache_ttl,			virtual_cwd_globals,	cwd_globals)
631 
632 	STD_PHP_INI_ENTRY("user_ini.filename",		".user.ini",	PHP_INI_SYSTEM,		OnUpdateString,		user_ini_filename,	php_core_globals,		core_globals)
633 	STD_PHP_INI_ENTRY("user_ini.cache_ttl",		"300",			PHP_INI_SYSTEM,		OnUpdateLong,		user_ini_cache_ttl,	php_core_globals,		core_globals)
634 	STD_PHP_INI_ENTRY("hard_timeout",			"2",			PHP_INI_SYSTEM,		OnUpdateLong,		hard_timeout,		zend_executor_globals,	executor_globals)
635 #ifdef PHP_WIN32
636 	STD_PHP_INI_BOOLEAN("windows.show_crt_warning",		"0",		PHP_INI_ALL,		OnUpdateBool,			windows_show_crt_warning,			php_core_globals,	core_globals)
637 #endif
638 PHP_INI_END()
639 /* }}} */
640 
641 /* True globals (no need for thread safety */
642 /* But don't make them a single int bitfield */
643 static int module_initialized = 0;
644 static int module_startup = 1;
645 static int module_shutdown = 0;
646 
647 /* {{{ php_during_module_startup */
php_during_module_startup(void)648 static int php_during_module_startup(void)
649 {
650 	return module_startup;
651 }
652 /* }}} */
653 
654 /* {{{ php_during_module_shutdown */
php_during_module_shutdown(void)655 static int php_during_module_shutdown(void)
656 {
657 	return module_shutdown;
658 }
659 /* }}} */
660 
661 /* {{{ php_get_module_initialized
662  */
php_get_module_initialized(void)663 PHPAPI int php_get_module_initialized(void)
664 {
665 	return module_initialized;
666 }
667 /* }}} */
668 
669 /* {{{ php_log_err_with_severity
670  */
php_log_err_with_severity(char * log_message,int syslog_type_int)671 PHPAPI ZEND_COLD void php_log_err_with_severity(char *log_message, int syslog_type_int)
672 {
673 	int fd = -1;
674 	time_t error_time;
675 
676 	if (PG(in_error_log)) {
677 		/* prevent recursive invocation */
678 		return;
679 	}
680 	PG(in_error_log) = 1;
681 
682 	/* Try to use the specified logging location. */
683 	if (PG(error_log) != NULL) {
684 #ifdef HAVE_SYSLOG_H
685 		if (!strcmp(PG(error_log), "syslog")) {
686 			php_syslog(syslog_type_int, "%s", log_message);
687 			PG(in_error_log) = 0;
688 			return;
689 		}
690 #endif
691 		fd = VCWD_OPEN_MODE(PG(error_log), O_CREAT | O_APPEND | O_WRONLY, 0644);
692 		if (fd != -1) {
693 			char *tmp;
694 			size_t len;
695 			zend_string *error_time_str;
696 
697 			time(&error_time);
698 #ifdef ZTS
699 			if (!php_during_module_startup()) {
700 				error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1);
701 			} else {
702 				error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 0);
703 			}
704 #else
705 			error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1);
706 #endif
707 			len = spprintf(&tmp, 0, "[%s] %s%s", ZSTR_VAL(error_time_str), log_message, PHP_EOL);
708 #ifdef PHP_WIN32
709 			php_flock(fd, 2);
710 			/* XXX should eventually write in a loop if len > UINT_MAX */
711 			php_ignore_value(write(fd, tmp, (unsigned)len));
712 #else
713 			php_ignore_value(write(fd, tmp, len));
714 #endif
715 			efree(tmp);
716 			zend_string_free(error_time_str);
717 			close(fd);
718 			PG(in_error_log) = 0;
719 			return;
720 		}
721 	}
722 
723 	/* Otherwise fall back to the default logging location, if we have one */
724 
725 	if (sapi_module.log_message) {
726 		sapi_module.log_message(log_message, syslog_type_int);
727 	}
728 	PG(in_error_log) = 0;
729 }
730 /* }}} */
731 
732 /* {{{ php_write
733    wrapper for modules to use PHPWRITE */
php_write(void * buf,size_t size)734 PHPAPI size_t php_write(void *buf, size_t size)
735 {
736 	return PHPWRITE(buf, size);
737 }
738 /* }}} */
739 
740 /* {{{ php_printf
741  */
php_printf(const char * format,...)742 PHPAPI size_t php_printf(const char *format, ...)
743 {
744 	va_list args;
745 	size_t ret;
746 	char *buffer;
747 	size_t size;
748 
749 	va_start(args, format);
750 	size = vspprintf(&buffer, 0, format, args);
751 	ret = PHPWRITE(buffer, size);
752 	efree(buffer);
753 	va_end(args);
754 
755 	return ret;
756 }
757 /* }}} */
758 
759 /* {{{ php_verror */
760 /* php_verror is called from php_error_docref<n> functions.
761  * Its purpose is to unify error messages and automatically generate clickable
762  * html error messages if correcponding ini setting (html_errors) is activated.
763  * See: CODING_STANDARDS for details.
764  */
php_verror(const char * docref,const char * params,int type,const char * format,va_list args)765 PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int type, const char *format, va_list args)
766 {
767 	zend_string *replace_buffer = NULL, *replace_origin = NULL;
768 	char *buffer = NULL, *docref_buf = NULL, *target = NULL;
769 	char *docref_target = "", *docref_root = "";
770 	char *p;
771 	int buffer_len = 0;
772 	const char *space = "";
773 	const char *class_name = "";
774 	const char *function;
775 	int origin_len;
776 	char *origin;
777 	char *message;
778 	int is_function = 0;
779 
780 	/* get error text into buffer and escape for html if necessary */
781 	buffer_len = (int)vspprintf(&buffer, 0, format, args);
782 
783 	if (PG(html_errors)) {
784 		replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, get_safe_charset_hint());
785 		/* Retry with substituting invalid chars on fail. */
786 		if (!replace_buffer || ZSTR_LEN(replace_buffer) < 1) {
787 			replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT | ENT_HTML_SUBSTITUTE_ERRORS, get_safe_charset_hint());
788 		}
789 
790 		efree(buffer);
791 
792 		if (replace_buffer) {
793 			buffer = ZSTR_VAL(replace_buffer);
794 			buffer_len = (int)ZSTR_LEN(replace_buffer);
795 		} else {
796 			buffer = "";
797 			buffer_len = 0;
798 		}
799 	}
800 
801 	/* which function caused the problem if any at all */
802 	if (php_during_module_startup()) {
803 		function = "PHP Startup";
804 	} else if (php_during_module_shutdown()) {
805 		function = "PHP Shutdown";
806 	} else if (EG(current_execute_data) &&
807 				EG(current_execute_data)->func &&
808 				ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
809 				EG(current_execute_data)->opline &&
810 				EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL
811 	) {
812 		switch (EG(current_execute_data)->opline->extended_value) {
813 			case ZEND_EVAL:
814 				function = "eval";
815 				is_function = 1;
816 				break;
817 			case ZEND_INCLUDE:
818 				function = "include";
819 				is_function = 1;
820 				break;
821 			case ZEND_INCLUDE_ONCE:
822 				function = "include_once";
823 				is_function = 1;
824 				break;
825 			case ZEND_REQUIRE:
826 				function = "require";
827 				is_function = 1;
828 				break;
829 			case ZEND_REQUIRE_ONCE:
830 				function = "require_once";
831 				is_function = 1;
832 				break;
833 			default:
834 				function = "Unknown";
835 		}
836 	} else {
837 		function = get_active_function_name();
838 		if (!function || !strlen(function)) {
839 			function = "Unknown";
840 		} else {
841 			is_function = 1;
842 			class_name = get_active_class_name(&space);
843 		}
844 	}
845 
846 	/* if we still have memory then format the origin */
847 	if (is_function) {
848 		origin_len = (int)spprintf(&origin, 0, "%s%s%s(%s)", class_name, space, function, params);
849 	} else {
850 		origin_len = (int)spprintf(&origin, 0, "%s", function);
851 	}
852 
853 	if (PG(html_errors)) {
854 		replace_origin = php_escape_html_entities((unsigned char*)origin, origin_len, 0, ENT_COMPAT, get_safe_charset_hint());
855 		efree(origin);
856 		origin = ZSTR_VAL(replace_origin);
857 	}
858 
859 	/* origin and buffer available, so lets come up with the error message */
860 	if (docref && docref[0] == '#') {
861 		docref_target = strchr(docref, '#');
862 		docref = NULL;
863 	}
864 
865 	/* no docref given but function is known (the default) */
866 	if (!docref && is_function) {
867 		int doclen;
868 		while (*function == '_') {
869 			function++;
870 		}
871 		if (space[0] == '\0') {
872 			doclen = (int)spprintf(&docref_buf, 0, "function.%s", function);
873 		} else {
874 			doclen = (int)spprintf(&docref_buf, 0, "%s.%s", class_name, function);
875 		}
876 		while((p = strchr(docref_buf, '_')) != NULL) {
877 			*p = '-';
878 		}
879 		docref = php_strtolower(docref_buf, doclen);
880 	}
881 
882 	/* we have a docref for a function AND
883 	 * - we show errors in html mode AND
884 	 * - the user wants to see the links
885 	 */
886 	if (docref && is_function && PG(html_errors) && strlen(PG(docref_root))) {
887 		if (strncmp(docref, "http://", 7)) {
888 			/* We don't have 'http://' so we use docref_root */
889 
890 			char *ref;  /* temp copy for duplicated docref */
891 
892 			docref_root = PG(docref_root);
893 
894 			ref = estrdup(docref);
895 			if (docref_buf) {
896 				efree(docref_buf);
897 			}
898 			docref_buf = ref;
899 			/* strip of the target if any */
900 			p = strrchr(ref, '#');
901 			if (p) {
902 				target = estrdup(p);
903 				if (target) {
904 					docref_target = target;
905 					*p = '\0';
906 				}
907 			}
908 			/* add the extension if it is set in ini */
909 			if (PG(docref_ext) && strlen(PG(docref_ext))) {
910 				spprintf(&docref_buf, 0, "%s%s", ref, PG(docref_ext));
911 				efree(ref);
912 			}
913 			docref = docref_buf;
914 		}
915 		/* display html formatted or only show the additional links */
916 		if (PG(html_errors)) {
917 			spprintf(&message, 0, "%s [<a href='%s%s%s'>%s</a>]: %s", origin, docref_root, docref, docref_target, docref, buffer);
918 		} else {
919 			spprintf(&message, 0, "%s [%s%s%s]: %s", origin, docref_root, docref, docref_target, buffer);
920 		}
921 		if (target) {
922 			efree(target);
923 		}
924 	} else {
925 		spprintf(&message, 0, "%s: %s", origin, buffer);
926 	}
927 	if (replace_origin) {
928 		zend_string_free(replace_origin);
929 	} else {
930 		efree(origin);
931 	}
932 	if (docref_buf) {
933 		efree(docref_buf);
934 	}
935 
936 	if (PG(track_errors) && module_initialized && EG(active) &&
937 			(Z_TYPE(EG(user_error_handler)) == IS_UNDEF || !(EG(user_error_handler_error_reporting) & type))) {
938 		zval tmp;
939 		ZVAL_STRINGL(&tmp, buffer, buffer_len);
940 		if (EG(current_execute_data)) {
941 			if (zend_set_local_var_str("php_errormsg", sizeof("php_errormsg")-1, &tmp, 0) == FAILURE) {
942 				zval_ptr_dtor(&tmp);
943 			}
944 		} else {
945 			zend_hash_str_update_ind(&EG(symbol_table), "php_errormsg", sizeof("php_errormsg")-1, &tmp);
946 		}
947 	}
948 	if (replace_buffer) {
949 		zend_string_free(replace_buffer);
950 	} else {
951 		if (buffer_len > 0) {
952 			efree(buffer);
953 		}
954 	}
955 
956 	php_error(type, "%s", message);
957 	efree(message);
958 }
959 /* }}} */
960 
961 /* {{{ php_error_docref0 */
962 /* See: CODING_STANDARDS for details. */
php_error_docref0(const char * docref,int type,const char * format,...)963 PHPAPI ZEND_COLD void php_error_docref0(const char *docref, int type, const char *format, ...)
964 {
965 	va_list args;
966 
967 	va_start(args, format);
968 	php_verror(docref, "", type, format, args);
969 	va_end(args);
970 }
971 /* }}} */
972 
973 /* {{{ php_error_docref1 */
974 /* See: CODING_STANDARDS for details. */
php_error_docref1(const char * docref,const char * param1,int type,const char * format,...)975 PHPAPI ZEND_COLD void php_error_docref1(const char *docref, const char *param1, int type, const char *format, ...)
976 {
977 	va_list args;
978 
979 	va_start(args, format);
980 	php_verror(docref, param1, type, format, args);
981 	va_end(args);
982 }
983 /* }}} */
984 
985 /* {{{ php_error_docref2 */
986 /* See: CODING_STANDARDS for details. */
php_error_docref2(const char * docref,const char * param1,const char * param2,int type,const char * format,...)987 PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1, const char *param2, int type, const char *format, ...)
988 {
989 	char *params;
990 	va_list args;
991 
992 	spprintf(&params, 0, "%s,%s", param1, param2);
993 	va_start(args, format);
994 	php_verror(docref, params ? params : "...", type, format, args);
995 	va_end(args);
996 	if (params) {
997 		efree(params);
998 	}
999 }
1000 /* }}} */
1001 
1002 #ifdef PHP_WIN32
1003 #define PHP_WIN32_ERROR_MSG_BUFFER_SIZE 512
php_win32_docref2_from_error(DWORD error,const char * param1,const char * param2)1004 PHPAPI ZEND_COLD void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2) {
1005 	if (error == 0) {
1006 		php_error_docref2(NULL, param1, param2, E_WARNING, "%s", strerror(errno));
1007 	} else {
1008 		char buf[PHP_WIN32_ERROR_MSG_BUFFER_SIZE + 1];
1009 		int buf_len;
1010 
1011 		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, buf, PHP_WIN32_ERROR_MSG_BUFFER_SIZE, NULL);
1012 		buf_len = (int)strlen(buf);
1013 		if (buf_len >= 2) {
1014 			buf[buf_len - 1] = '\0';
1015 			buf[buf_len - 2] = '\0';
1016 		}
1017 		php_error_docref2(NULL, param1, param2, E_WARNING, "%s (code: %lu)", (char *)buf, error);
1018 	}
1019 }
1020 #undef PHP_WIN32_ERROR_MSG_BUFFER_SIZE
1021 #endif
1022 
1023 /* {{{ php_html_puts */
php_html_puts(const char * str,size_t size)1024 PHPAPI void php_html_puts(const char *str, size_t size)
1025 {
1026 	zend_html_puts(str, size);
1027 }
1028 /* }}} */
1029 
1030 /* {{{ php_error_cb
1031  extended error handling function */
php_error_cb(int type,const char * error_filename,const uint32_t error_lineno,const char * format,va_list args)1032 static ZEND_COLD void php_error_cb(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args)
1033 {
1034 	char *buffer;
1035 	int buffer_len, display;
1036 
1037 	buffer_len = (int)vspprintf(&buffer, PG(log_errors_max_len), format, args);
1038 
1039 	/* check for repeated errors to be ignored */
1040 	if (PG(ignore_repeated_errors) && PG(last_error_message)) {
1041 		/* no check for PG(last_error_file) is needed since it cannot
1042 		 * be NULL if PG(last_error_message) is not NULL */
1043 		if (strcmp(PG(last_error_message), buffer)
1044 			|| (!PG(ignore_repeated_source)
1045 				&& ((PG(last_error_lineno) != (int)error_lineno)
1046 					|| strcmp(PG(last_error_file), error_filename)))) {
1047 			display = 1;
1048 		} else {
1049 			display = 0;
1050 		}
1051 	} else {
1052 		display = 1;
1053 	}
1054 
1055 	/* store the error if it has changed */
1056 	if (display) {
1057 		if (PG(last_error_message)) {
1058 			char *s = PG(last_error_message);
1059 			PG(last_error_message) = NULL;
1060 			free(s);
1061 		}
1062 		if (PG(last_error_file)) {
1063 			char *s = PG(last_error_file);
1064 			PG(last_error_file) = NULL;
1065 			free(s);
1066 		}
1067 		if (!error_filename) {
1068 			error_filename = "Unknown";
1069 		}
1070 		PG(last_error_type) = type;
1071 		PG(last_error_message) = strdup(buffer);
1072 		PG(last_error_file) = strdup(error_filename);
1073 		PG(last_error_lineno) = error_lineno;
1074 	}
1075 
1076 	/* according to error handling mode, suppress error, throw exception or show it */
1077 	if (EG(error_handling) != EH_NORMAL) {
1078 		switch (type) {
1079 			case E_ERROR:
1080 			case E_CORE_ERROR:
1081 			case E_COMPILE_ERROR:
1082 			case E_USER_ERROR:
1083 			case E_PARSE:
1084 				/* fatal errors are real errors and cannot be made exceptions */
1085 				break;
1086 			case E_STRICT:
1087 			case E_DEPRECATED:
1088 			case E_USER_DEPRECATED:
1089 				/* for the sake of BC to old damaged code */
1090 				break;
1091 			case E_NOTICE:
1092 			case E_USER_NOTICE:
1093 				/* notices are no errors and are not treated as such like E_WARNINGS */
1094 				break;
1095 			default:
1096 				/* throw an exception if we are in EH_THROW mode
1097 				 * but DO NOT overwrite a pending exception
1098 				 */
1099 				if (EG(error_handling) == EH_THROW && !EG(exception)) {
1100 					zend_throw_error_exception(EG(exception_class), buffer, 0, type);
1101 				}
1102 				efree(buffer);
1103 				return;
1104 		}
1105 	}
1106 
1107 	/* display/log the error if necessary */
1108 	if (display && (EG(error_reporting) & type || (type & E_CORE))
1109 		&& (PG(log_errors) || PG(display_errors) || (!module_initialized))) {
1110 		char *error_type_str;
1111 		int syslog_type_int = LOG_NOTICE;
1112 
1113 		switch (type) {
1114 			case E_ERROR:
1115 			case E_CORE_ERROR:
1116 			case E_COMPILE_ERROR:
1117 			case E_USER_ERROR:
1118 				error_type_str = "Fatal error";
1119 				syslog_type_int = LOG_ERR;
1120 				break;
1121 			case E_RECOVERABLE_ERROR:
1122 				error_type_str = "Recoverable fatal error";
1123 				syslog_type_int = LOG_ERR;
1124 				break;
1125 			case E_WARNING:
1126 			case E_CORE_WARNING:
1127 			case E_COMPILE_WARNING:
1128 			case E_USER_WARNING:
1129 				error_type_str = "Warning";
1130 				syslog_type_int = LOG_WARNING;
1131 				break;
1132 			case E_PARSE:
1133 				error_type_str = "Parse error";
1134 				syslog_type_int = LOG_ERR;
1135 				break;
1136 			case E_NOTICE:
1137 			case E_USER_NOTICE:
1138 				error_type_str = "Notice";
1139 				syslog_type_int = LOG_NOTICE;
1140 				break;
1141 			case E_STRICT:
1142 				error_type_str = "Strict Standards";
1143 				syslog_type_int = LOG_INFO;
1144 				break;
1145 			case E_DEPRECATED:
1146 			case E_USER_DEPRECATED:
1147 				error_type_str = "Deprecated";
1148 				syslog_type_int = LOG_INFO;
1149 				break;
1150 			default:
1151 				error_type_str = "Unknown error";
1152 				break;
1153 		}
1154 
1155 		if (!module_initialized || PG(log_errors)) {
1156 			char *log_buffer;
1157 #ifdef PHP_WIN32
1158 			if (type == E_CORE_ERROR || type == E_CORE_WARNING) {
1159 				syslog(LOG_ALERT, "PHP %s: %s (%s)", error_type_str, buffer, GetCommandLine());
1160 			}
1161 #endif
1162 			spprintf(&log_buffer, 0, "PHP %s:  %s in %s on line %d", error_type_str, buffer, error_filename, error_lineno);
1163 			php_log_err_with_severity(log_buffer, syslog_type_int);
1164 			efree(log_buffer);
1165 		}
1166 
1167 		if (PG(display_errors) && ((module_initialized && !PG(during_request_startup)) || (PG(display_startup_errors)))) {
1168 			if (PG(xmlrpc_errors)) {
1169 				php_printf("<?xml version=\"1.0\"?><methodResponse><fault><value><struct><member><name>faultCode</name><value><int>" ZEND_LONG_FMT "</int></value></member><member><name>faultString</name><value><string>%s:%s in %s on line %d</string></value></member></struct></value></fault></methodResponse>", PG(xmlrpc_error_number), error_type_str, buffer, error_filename, error_lineno);
1170 			} else {
1171 				char *prepend_string = INI_STR("error_prepend_string");
1172 				char *append_string = INI_STR("error_append_string");
1173 
1174 				if (PG(html_errors)) {
1175 					if (type == E_ERROR || type == E_PARSE) {
1176 						zend_string *buf = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, get_safe_charset_hint());
1177 						php_printf("%s<br />\n<b>%s</b>:  %s in <b>%s</b> on line <b>%d</b><br />\n%s", STR_PRINT(prepend_string), error_type_str, ZSTR_VAL(buf), error_filename, error_lineno, STR_PRINT(append_string));
1178 						zend_string_free(buf);
1179 					} else {
1180 						php_printf("%s<br />\n<b>%s</b>:  %s in <b>%s</b> on line <b>%d</b><br />\n%s", STR_PRINT(prepend_string), error_type_str, buffer, error_filename, error_lineno, STR_PRINT(append_string));
1181 					}
1182 				} else {
1183 					/* Write CLI/CGI errors to stderr if display_errors = "stderr" */
1184 					if ((!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "cgi") || !strcmp(sapi_module.name, "phpdbg")) &&
1185 						PG(display_errors) == PHP_DISPLAY_ERRORS_STDERR
1186 					) {
1187 						fprintf(stderr, "%s: %s in %s on line %u\n", error_type_str, buffer, error_filename, error_lineno);
1188 #ifdef PHP_WIN32
1189 						fflush(stderr);
1190 #endif
1191 					} else {
1192 						php_printf("%s\n%s: %s in %s on line %d\n%s", STR_PRINT(prepend_string), error_type_str, buffer, error_filename, error_lineno, STR_PRINT(append_string));
1193 					}
1194 				}
1195 			}
1196 		}
1197 #if ZEND_DEBUG
1198 		if (PG(report_zend_debug)) {
1199 			zend_bool trigger_break;
1200 
1201 			switch (type) {
1202 				case E_ERROR:
1203 				case E_CORE_ERROR:
1204 				case E_COMPILE_ERROR:
1205 				case E_USER_ERROR:
1206 					trigger_break=1;
1207 					break;
1208 				default:
1209 					trigger_break=0;
1210 					break;
1211 			}
1212 			zend_output_debug_string(trigger_break, "%s(%d) : %s - %s", error_filename, error_lineno, error_type_str, buffer);
1213 		}
1214 #endif
1215 	}
1216 
1217 	/* Bail out if we can't recover */
1218 	switch (type) {
1219 		case E_CORE_ERROR:
1220 			if(!module_initialized) {
1221 				/* bad error in module startup - no way we can live with this */
1222 				exit(-2);
1223 			}
1224 		/* no break - intentionally */
1225 		case E_ERROR:
1226 		case E_RECOVERABLE_ERROR:
1227 		case E_PARSE:
1228 		case E_COMPILE_ERROR:
1229 		case E_USER_ERROR:
1230 			EG(exit_status) = 255;
1231 			if (module_initialized) {
1232 				if (!PG(display_errors) &&
1233 				    !SG(headers_sent) &&
1234 					SG(sapi_headers).http_response_code == 200
1235 				) {
1236 					sapi_header_line ctr = {0};
1237 
1238 					ctr.line = "HTTP/1.0 500 Internal Server Error";
1239 					ctr.line_len = sizeof("HTTP/1.0 500 Internal Server Error") - 1;
1240 					sapi_header_op(SAPI_HEADER_REPLACE, &ctr);
1241 				}
1242 				/* the parser would return 1 (failure), we can bail out nicely */
1243 				if (type != E_PARSE) {
1244 					/* restore memory limit */
1245 					zend_set_memory_limit(PG(memory_limit));
1246 					efree(buffer);
1247 					zend_objects_store_mark_destructed(&EG(objects_store));
1248 					zend_bailout();
1249 					return;
1250 				}
1251 			}
1252 			break;
1253 	}
1254 
1255 	/* Log if necessary */
1256 	if (!display) {
1257 		efree(buffer);
1258 		return;
1259 	}
1260 
1261 	if (PG(track_errors) && module_initialized && EG(active)) {
1262 		zval tmp;
1263 
1264 		ZVAL_STRINGL(&tmp, buffer, buffer_len);
1265 		if (EG(current_execute_data)) {
1266 			if (zend_set_local_var_str("php_errormsg", sizeof("php_errormsg")-1, &tmp, 0) == FAILURE) {
1267 				zval_ptr_dtor(&tmp);
1268 			}
1269 		} else {
1270 			zend_hash_str_update_ind(&EG(symbol_table), "php_errormsg", sizeof("php_errormsg")-1, &tmp);
1271 		}
1272 	}
1273 
1274 	efree(buffer);
1275 }
1276 /* }}} */
1277 
1278 /* {{{ php_get_current_user
1279  */
php_get_current_user(void)1280 PHPAPI char *php_get_current_user(void)
1281 {
1282 	zend_stat_t *pstat;
1283 
1284 	if (SG(request_info).current_user) {
1285 		return SG(request_info).current_user;
1286 	}
1287 
1288 	/* FIXME: I need to have this somehow handled if
1289 	USE_SAPI is defined, because cgi will also be
1290 	interfaced in USE_SAPI */
1291 
1292 	pstat = sapi_get_stat();
1293 
1294 	if (!pstat) {
1295 		return "";
1296 	} else {
1297 #ifdef PHP_WIN32
1298 		char *name = php_win32_get_username();
1299 		int len;
1300 
1301 		if (!name) {
1302 			return "";
1303 		}
1304 		len = (int)strlen(name);
1305 		name[len] = '\0';
1306 		SG(request_info).current_user_length = len;
1307 		SG(request_info).current_user = estrndup(name, len);
1308 		free(name);
1309 		return SG(request_info).current_user;
1310 #else
1311 		struct passwd *pwd;
1312 #if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX)
1313 		struct passwd _pw;
1314 		struct passwd *retpwptr = NULL;
1315 		int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
1316 		char *pwbuf;
1317 
1318 		if (pwbuflen < 1) {
1319 			return "";
1320 		}
1321 		pwbuf = emalloc(pwbuflen);
1322 		if (getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr) != 0) {
1323 			efree(pwbuf);
1324 			return "";
1325 		}
1326 		if (retpwptr == NULL) {
1327 			efree(pwbuf);
1328 			return "";
1329 		}
1330 		pwd = &_pw;
1331 #else
1332 		if ((pwd=getpwuid(pstat->st_uid))==NULL) {
1333 			return "";
1334 		}
1335 #endif
1336 		SG(request_info).current_user_length = strlen(pwd->pw_name);
1337 		SG(request_info).current_user = estrndup(pwd->pw_name, SG(request_info).current_user_length);
1338 #if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX)
1339 		efree(pwbuf);
1340 #endif
1341 		return SG(request_info).current_user;
1342 #endif
1343 	}
1344 }
1345 /* }}} */
1346 
1347 /* {{{ proto bool set_time_limit(int seconds)
1348    Sets the maximum time a script can run */
PHP_FUNCTION(set_time_limit)1349 PHP_FUNCTION(set_time_limit)
1350 {
1351 	zend_long new_timeout;
1352 	char *new_timeout_str;
1353 	int new_timeout_strlen;
1354 	zend_string *key;
1355 
1356 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &new_timeout) == FAILURE) {
1357 		return;
1358 	}
1359 
1360 	new_timeout_strlen = (int)zend_spprintf(&new_timeout_str, 0, ZEND_LONG_FMT, new_timeout);
1361 
1362 	key = zend_string_init("max_execution_time", sizeof("max_execution_time")-1, 0);
1363 	if (zend_alter_ini_entry_chars_ex(key, new_timeout_str, new_timeout_strlen, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == SUCCESS) {
1364 		RETVAL_TRUE;
1365 	} else {
1366 		RETVAL_FALSE;
1367 	}
1368 	zend_string_release(key);
1369 	efree(new_timeout_str);
1370 }
1371 /* }}} */
1372 
1373 /* {{{ php_fopen_wrapper_for_zend
1374  */
php_fopen_wrapper_for_zend(const char * filename,zend_string ** opened_path)1375 static FILE *php_fopen_wrapper_for_zend(const char *filename, zend_string **opened_path)
1376 {
1377 	return php_stream_open_wrapper_as_file((char *)filename, "rb", USE_PATH|IGNORE_URL_WIN|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE, opened_path);
1378 }
1379 /* }}} */
1380 
php_zend_stream_closer(void * handle)1381 static void php_zend_stream_closer(void *handle) /* {{{ */
1382 {
1383 	php_stream_close((php_stream*)handle);
1384 }
1385 /* }}} */
1386 
php_zend_stream_mmap_closer(void * handle)1387 static void php_zend_stream_mmap_closer(void *handle) /* {{{ */
1388 {
1389 	php_stream_mmap_unmap((php_stream*)handle);
1390 	php_zend_stream_closer(handle);
1391 }
1392 /* }}} */
1393 
php_zend_stream_fsizer(void * handle)1394 static size_t php_zend_stream_fsizer(void *handle) /* {{{ */
1395 {
1396 	php_stream_statbuf  ssb;
1397 	if (php_stream_stat((php_stream*)handle, &ssb) == 0) {
1398 		return ssb.sb.st_size;
1399 	}
1400 	return 0;
1401 }
1402 /* }}} */
1403 
php_stream_open_for_zend(const char * filename,zend_file_handle * handle)1404 static int php_stream_open_for_zend(const char *filename, zend_file_handle *handle) /* {{{ */
1405 {
1406 	return php_stream_open_for_zend_ex(filename, handle, USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE);
1407 }
1408 /* }}} */
1409 
php_stream_open_for_zend_ex(const char * filename,zend_file_handle * handle,int mode)1410 PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode) /* {{{ */
1411 {
1412 	char *p;
1413 	size_t len, mapped_len;
1414 	php_stream *stream = php_stream_open_wrapper((char *)filename, "rb", mode, &handle->opened_path);
1415 
1416 	if (stream) {
1417 #if HAVE_MMAP || defined(PHP_WIN32)
1418 		size_t page_size = REAL_PAGE_SIZE;
1419 #endif
1420 
1421 		handle->filename = (char*)filename;
1422 		handle->free_filename = 0;
1423 		handle->handle.stream.handle  = stream;
1424 		handle->handle.stream.reader  = (zend_stream_reader_t)_php_stream_read;
1425 		handle->handle.stream.fsizer  = php_zend_stream_fsizer;
1426 		handle->handle.stream.isatty  = 0;
1427 		/* can we mmap immediately? */
1428 		memset(&handle->handle.stream.mmap, 0, sizeof(handle->handle.stream.mmap));
1429 		len = php_zend_stream_fsizer(stream);
1430 		if (len != 0
1431 #if HAVE_MMAP || defined(PHP_WIN32)
1432 		&& ((len - 1) % page_size) <= page_size - ZEND_MMAP_AHEAD
1433 #endif
1434 		&& php_stream_mmap_possible(stream)
1435 		&& (p = php_stream_mmap_range(stream, 0, len, PHP_STREAM_MAP_MODE_SHARED_READONLY, &mapped_len)) != NULL) {
1436 			handle->handle.stream.closer   = php_zend_stream_mmap_closer;
1437 			handle->handle.stream.mmap.buf = p;
1438 			handle->handle.stream.mmap.len = mapped_len;
1439 			handle->type = ZEND_HANDLE_MAPPED;
1440 		} else {
1441 			handle->handle.stream.closer = php_zend_stream_closer;
1442 			handle->type = ZEND_HANDLE_STREAM;
1443 		}
1444 		/* suppress warning if this stream is not explicitly closed */
1445 		php_stream_auto_cleanup(stream);
1446 
1447 		return SUCCESS;
1448 	}
1449 	return FAILURE;
1450 }
1451 /* }}} */
1452 
php_resolve_path_for_zend(const char * filename,int filename_len)1453 static zend_string *php_resolve_path_for_zend(const char *filename, int filename_len) /* {{{ */
1454 {
1455 	return php_resolve_path(filename, filename_len, PG(include_path));
1456 }
1457 /* }}} */
1458 
1459 /* {{{ php_get_configuration_directive_for_zend
1460  */
php_get_configuration_directive_for_zend(zend_string * name)1461 static zval *php_get_configuration_directive_for_zend(zend_string *name)
1462 {
1463 	return cfg_get_entry_ex(name);
1464 }
1465 /* }}} */
1466 
1467 /* {{{ php_free_request_globals
1468  */
php_free_request_globals(void)1469 static void php_free_request_globals(void)
1470 {
1471 	if (PG(last_error_message)) {
1472 		free(PG(last_error_message));
1473 		PG(last_error_message) = NULL;
1474 	}
1475 	if (PG(last_error_file)) {
1476 		free(PG(last_error_file));
1477 		PG(last_error_file) = NULL;
1478 	}
1479 	if (PG(php_sys_temp_dir)) {
1480 		efree(PG(php_sys_temp_dir));
1481 		PG(php_sys_temp_dir) = NULL;
1482 	}
1483 }
1484 /* }}} */
1485 
1486 /* {{{ php_message_handler_for_zend
1487  */
php_message_handler_for_zend(zend_long message,const void * data)1488 static ZEND_COLD void php_message_handler_for_zend(zend_long message, const void *data)
1489 {
1490 	switch (message) {
1491 		case ZMSG_FAILED_INCLUDE_FOPEN:
1492 			php_error_docref("function.include", E_WARNING, "Failed opening '%s' for inclusion (include_path='%s')", php_strip_url_passwd((char *) data), STR_PRINT(PG(include_path)));
1493 			break;
1494 		case ZMSG_FAILED_REQUIRE_FOPEN:
1495 			php_error_docref("function.require", E_COMPILE_ERROR, "Failed opening required '%s' (include_path='%s')", php_strip_url_passwd((char *) data), STR_PRINT(PG(include_path)));
1496 			break;
1497 		case ZMSG_FAILED_HIGHLIGHT_FOPEN:
1498 			php_error_docref(NULL, E_WARNING, "Failed opening '%s' for highlighting", php_strip_url_passwd((char *) data));
1499 			break;
1500 		case ZMSG_MEMORY_LEAK_DETECTED:
1501 		case ZMSG_MEMORY_LEAK_REPEATED:
1502 #if ZEND_DEBUG
1503 			if (EG(error_reporting) & E_WARNING) {
1504 				char memory_leak_buf[1024];
1505 
1506 				if (message==ZMSG_MEMORY_LEAK_DETECTED) {
1507 					zend_leak_info *t = (zend_leak_info *) data;
1508 
1509 					snprintf(memory_leak_buf, 512, "%s(%d) :  Freeing " ZEND_ADDR_FMT " (%zu bytes), script=%s\n", t->filename, t->lineno, (size_t)t->addr, t->size, SAFE_FILENAME(SG(request_info).path_translated));
1510 					if (t->orig_filename) {
1511 						char relay_buf[512];
1512 
1513 						snprintf(relay_buf, 512, "%s(%d) : Actual location (location was relayed)\n", t->orig_filename, t->orig_lineno);
1514 						strlcat(memory_leak_buf, relay_buf, sizeof(memory_leak_buf));
1515 					}
1516 				} else {
1517 					unsigned long leak_count = (zend_uintptr_t) data;
1518 
1519 					snprintf(memory_leak_buf, 512, "Last leak repeated %ld time%s\n", leak_count, (leak_count>1?"s":""));
1520 				}
1521 #	if defined(PHP_WIN32)
1522 				OutputDebugString(memory_leak_buf);
1523 #	else
1524 				fprintf(stderr, "%s", memory_leak_buf);
1525 #	endif
1526 			}
1527 #endif
1528 			break;
1529 		case ZMSG_MEMORY_LEAKS_GRAND_TOTAL:
1530 #if ZEND_DEBUG
1531 			if (EG(error_reporting) & E_WARNING) {
1532 				char memory_leak_buf[512];
1533 
1534 				snprintf(memory_leak_buf, 512, "=== Total %d memory leaks detected ===\n", *((uint32_t *) data));
1535 #	if defined(PHP_WIN32)
1536 				OutputDebugString(memory_leak_buf);
1537 #	else
1538 				fprintf(stderr, "%s", memory_leak_buf);
1539 #	endif
1540 			}
1541 #endif
1542 			break;
1543 		case ZMSG_LOG_SCRIPT_NAME: {
1544 				struct tm *ta, tmbuf;
1545 				time_t curtime;
1546 				char *datetime_str, asctimebuf[52];
1547 				char memory_leak_buf[4096];
1548 
1549 				time(&curtime);
1550 				ta = php_localtime_r(&curtime, &tmbuf);
1551 				datetime_str = php_asctime_r(ta, asctimebuf);
1552 				if (datetime_str) {
1553 					datetime_str[strlen(datetime_str)-1]=0;	/* get rid of the trailing newline */
1554 					snprintf(memory_leak_buf, sizeof(memory_leak_buf), "[%s]  Script:  '%s'\n", datetime_str, SAFE_FILENAME(SG(request_info).path_translated));
1555 				} else {
1556 					snprintf(memory_leak_buf, sizeof(memory_leak_buf), "[null]  Script:  '%s'\n", SAFE_FILENAME(SG(request_info).path_translated));
1557 				}
1558 #	if defined(PHP_WIN32)
1559 				OutputDebugString(memory_leak_buf);
1560 #	else
1561 				fprintf(stderr, "%s", memory_leak_buf);
1562 #	endif
1563 			}
1564 			break;
1565 	}
1566 }
1567 /* }}} */
1568 
1569 
php_on_timeout(int seconds)1570 void php_on_timeout(int seconds)
1571 {
1572 	PG(connection_status) |= PHP_CONNECTION_TIMEOUT;
1573 }
1574 
1575 #if PHP_SIGCHILD
1576 /* {{{ sigchld_handler
1577  */
sigchld_handler(int apar)1578 static void sigchld_handler(int apar)
1579 {
1580 	int errno_save = errno;
1581 
1582 	while (waitpid(-1, NULL, WNOHANG) > 0);
1583 	signal(SIGCHLD, sigchld_handler);
1584 
1585 	errno = errno_save;
1586 }
1587 /* }}} */
1588 #endif
1589 
1590 /* {{{ php_start_sapi()
1591  */
php_start_sapi(void)1592 static int php_start_sapi(void)
1593 {
1594 	int retval = SUCCESS;
1595 
1596 	if(!SG(sapi_started)) {
1597 		zend_try {
1598 			PG(during_request_startup) = 1;
1599 
1600 			/* initialize global variables */
1601 			PG(modules_activated) = 0;
1602 			PG(header_is_being_sent) = 0;
1603 			PG(connection_status) = PHP_CONNECTION_NORMAL;
1604 
1605 			zend_activate();
1606 			zend_set_timeout(EG(timeout_seconds), 1);
1607 			zend_activate_modules();
1608 			PG(modules_activated)=1;
1609 		} zend_catch {
1610 			retval = FAILURE;
1611 		} zend_end_try();
1612 
1613 		SG(sapi_started) = 1;
1614 	}
1615 	return retval;
1616 }
1617 
1618 /* }}} */
1619 
1620 /* {{{ php_request_startup
1621  */
1622 #ifndef APACHE_HOOKS
php_request_startup(void)1623 int php_request_startup(void)
1624 {
1625 	int retval = SUCCESS;
1626 
1627 	zend_interned_strings_activate();
1628 
1629 #ifdef HAVE_DTRACE
1630 	DTRACE_REQUEST_STARTUP(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
1631 #endif /* HAVE_DTRACE */
1632 
1633 #ifdef PHP_WIN32
1634 # if defined(ZTS)
1635 	_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
1636 # endif
1637 	PG(com_initialized) = 0;
1638 #endif
1639 
1640 #if PHP_SIGCHILD
1641 	signal(SIGCHLD, sigchld_handler);
1642 #endif
1643 
1644 	zend_try {
1645 		PG(in_error_log) = 0;
1646 		PG(during_request_startup) = 1;
1647 
1648 		php_output_activate();
1649 
1650 		/* initialize global variables */
1651 		PG(modules_activated) = 0;
1652 		PG(header_is_being_sent) = 0;
1653 		PG(connection_status) = PHP_CONNECTION_NORMAL;
1654 		PG(in_user_include) = 0;
1655 
1656 		zend_activate();
1657 		sapi_activate();
1658 
1659 #ifdef ZEND_SIGNALS
1660 		zend_signal_activate();
1661 #endif
1662 
1663 		if (PG(max_input_time) == -1) {
1664 			zend_set_timeout(EG(timeout_seconds), 1);
1665 		} else {
1666 			zend_set_timeout(PG(max_input_time), 1);
1667 		}
1668 
1669 		/* Disable realpath cache if an open_basedir is set */
1670 		if (PG(open_basedir) && *PG(open_basedir)) {
1671 			CWDG(realpath_cache_size_limit) = 0;
1672 		}
1673 
1674 		if (PG(expose_php)) {
1675 			sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
1676 		}
1677 
1678 		if (PG(output_handler) && PG(output_handler)[0]) {
1679 			zval oh;
1680 
1681 			ZVAL_STRING(&oh, PG(output_handler));
1682 			php_output_start_user(&oh, 0, PHP_OUTPUT_HANDLER_STDFLAGS);
1683 			zval_ptr_dtor(&oh);
1684 		} else if (PG(output_buffering)) {
1685 			php_output_start_user(NULL, PG(output_buffering) > 1 ? PG(output_buffering) : 0, PHP_OUTPUT_HANDLER_STDFLAGS);
1686 		} else if (PG(implicit_flush)) {
1687 			php_output_set_implicit_flush(1);
1688 		}
1689 
1690 		/* We turn this off in php_execute_script() */
1691 		/* PG(during_request_startup) = 0; */
1692 
1693 		php_hash_environment();
1694 		zend_activate_modules();
1695 		PG(modules_activated)=1;
1696 	} zend_catch {
1697 		retval = FAILURE;
1698 	} zend_end_try();
1699 
1700 	SG(sapi_started) = 1;
1701 
1702 	return retval;
1703 }
1704 # else
php_request_startup(void)1705 int php_request_startup(void)
1706 {
1707 	int retval = SUCCESS;
1708 
1709 	zend_interned_strings_activate();
1710 
1711 #if PHP_SIGCHILD
1712 	signal(SIGCHLD, sigchld_handler);
1713 #endif
1714 
1715 	if (php_start_sapi() == FAILURE) {
1716 		return FAILURE;
1717 	}
1718 
1719 	php_output_activate();
1720 	sapi_activate();
1721 	php_hash_environment();
1722 
1723 	zend_try {
1724 		PG(during_request_startup) = 1;
1725 		if (PG(expose_php)) {
1726 			sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
1727 		}
1728 	} zend_catch {
1729 		retval = FAILURE;
1730 	} zend_end_try();
1731 
1732 	return retval;
1733 }
1734 # endif
1735 /* }}} */
1736 
1737 /* {{{ php_request_startup_for_hook
1738  */
php_request_startup_for_hook(void)1739 int php_request_startup_for_hook(void)
1740 {
1741 	int retval = SUCCESS;
1742 
1743 	zend_interned_strings_activate();
1744 
1745 #if PHP_SIGCHLD
1746 	signal(SIGCHLD, sigchld_handler);
1747 #endif
1748 
1749 	if (php_start_sapi() == FAILURE) {
1750 		return FAILURE;
1751 	}
1752 
1753 	php_output_activate();
1754 	sapi_activate_headers_only();
1755 	php_hash_environment();
1756 
1757 	return retval;
1758 }
1759 /* }}} */
1760 
1761 /* {{{ php_request_shutdown_for_exec
1762  */
php_request_shutdown_for_exec(void * dummy)1763 void php_request_shutdown_for_exec(void *dummy)
1764 {
1765 
1766 	/* used to close fd's in the 3..255 range here, but it's problematic
1767 	 */
1768 	zend_interned_strings_deactivate();
1769 	shutdown_memory_manager(1, 1);
1770 }
1771 /* }}} */
1772 
1773 /* {{{ php_request_shutdown_for_hook
1774  */
php_request_shutdown_for_hook(void * dummy)1775 void php_request_shutdown_for_hook(void *dummy)
1776 {
1777 
1778 	if (PG(modules_activated)) zend_try {
1779 		php_call_shutdown_functions();
1780 	} zend_end_try();
1781 
1782 	if (PG(modules_activated)) {
1783 		zend_deactivate_modules();
1784 	}
1785 
1786 	if (PG(modules_activated)) {
1787 		php_free_shutdown_functions();
1788 	}
1789 
1790 	zend_try {
1791 		zend_unset_timeout();
1792 	} zend_end_try();
1793 
1794 	zend_try {
1795 		int i;
1796 
1797 		for (i = 0; i < NUM_TRACK_VARS; i++) {
1798 			zval_ptr_dtor(&PG(http_globals)[i]);
1799 		}
1800 	} zend_end_try();
1801 
1802 	zend_deactivate();
1803 
1804 	zend_try {
1805 		sapi_deactivate();
1806 	} zend_end_try();
1807 
1808 	zend_try {
1809 		php_shutdown_stream_hashes();
1810 	} zend_end_try();
1811 
1812 	zend_interned_strings_deactivate();
1813 
1814 	zend_try {
1815 		shutdown_memory_manager(CG(unclean_shutdown), 0);
1816 	} zend_end_try();
1817 
1818 #ifdef ZEND_SIGNALS
1819 	zend_try {
1820 		zend_signal_deactivate();
1821 	} zend_end_try();
1822 #endif
1823 }
1824 
1825 /* }}} */
1826 
1827 /* {{{ php_request_shutdown
1828  */
php_request_shutdown(void * dummy)1829 void php_request_shutdown(void *dummy)
1830 {
1831 	zend_bool report_memleaks;
1832 
1833 	EG(flags) |= EG_FLAGS_IN_SHUTDOWN;
1834 
1835 	report_memleaks = PG(report_memleaks);
1836 
1837 	/* EG(current_execute_data) points into nirvana and therefore cannot be safely accessed
1838 	 * inside zend_executor callback functions.
1839 	 */
1840 	EG(current_execute_data) = NULL;
1841 
1842 	php_deactivate_ticks();
1843 
1844 	/* 1. Call all possible shutdown functions registered with register_shutdown_function() */
1845 	if (PG(modules_activated)) zend_try {
1846 		php_call_shutdown_functions();
1847 	} zend_end_try();
1848 
1849 	/* 2. Call all possible __destruct() functions */
1850 	zend_try {
1851 		zend_call_destructors();
1852 	} zend_end_try();
1853 
1854 	/* 3. Flush all output buffers */
1855 	zend_try {
1856 		zend_bool send_buffer = SG(request_info).headers_only ? 0 : 1;
1857 
1858 		if (CG(unclean_shutdown) && PG(last_error_type) == E_ERROR &&
1859 			(size_t)PG(memory_limit) < zend_memory_usage(1)
1860 		) {
1861 			send_buffer = 0;
1862 		}
1863 
1864 		if (!send_buffer) {
1865 			php_output_discard_all();
1866 		} else {
1867 			php_output_end_all();
1868 		}
1869 	} zend_end_try();
1870 
1871 	/* 4. Reset max_execution_time (no longer executing php code after response sent) */
1872 	zend_try {
1873 		zend_unset_timeout();
1874 	} zend_end_try();
1875 
1876 	/* 5. Call all extensions RSHUTDOWN functions */
1877 	if (PG(modules_activated)) {
1878 		zend_deactivate_modules();
1879 	}
1880 
1881 	/* 6. Shutdown output layer (send the set HTTP headers, cleanup output handlers, etc.) */
1882 	zend_try {
1883 		php_output_deactivate();
1884 	} zend_end_try();
1885 
1886 	/* 7. Free shutdown functions */
1887 	if (PG(modules_activated)) {
1888 		php_free_shutdown_functions();
1889 	}
1890 
1891 	/* 8. Destroy super-globals */
1892 	zend_try {
1893 		int i;
1894 
1895 		for (i=0; i<NUM_TRACK_VARS; i++) {
1896 			zval_ptr_dtor(&PG(http_globals)[i]);
1897 		}
1898 	} zend_end_try();
1899 
1900 	/* 9. free request-bound globals */
1901 	php_free_request_globals();
1902 
1903 	/* 10. Shutdown scanner/executor/compiler and restore ini entries */
1904 	zend_deactivate();
1905 
1906 	/* 11. Call all extensions post-RSHUTDOWN functions */
1907 	zend_try {
1908 		zend_post_deactivate_modules();
1909 	} zend_end_try();
1910 
1911 	/* 12. SAPI related shutdown (free stuff) */
1912 	zend_try {
1913 		sapi_deactivate();
1914 	} zend_end_try();
1915 
1916 	/* 13. free virtual CWD memory */
1917 	virtual_cwd_deactivate();
1918 
1919 	/* 14. Destroy stream hashes */
1920 	zend_try {
1921 		php_shutdown_stream_hashes();
1922 	} zend_end_try();
1923 
1924 	/* 15. Free Willy (here be crashes) */
1925 	zend_interned_strings_deactivate();
1926 	zend_try {
1927 		shutdown_memory_manager(CG(unclean_shutdown) || !report_memleaks, 0);
1928 	} zend_end_try();
1929 
1930 	/* 16. Reset max_execution_time */
1931 	zend_try {
1932 		zend_unset_timeout();
1933 	} zend_end_try();
1934 
1935 	/* 17. Deactivate Zend signals */
1936 #ifdef ZEND_SIGNALS
1937 	zend_signal_deactivate();
1938 #endif
1939 
1940 #ifdef PHP_WIN32
1941 	if (PG(com_initialized)) {
1942 		CoUninitialize();
1943 		PG(com_initialized) = 0;
1944 	}
1945 #endif
1946 
1947 #ifdef HAVE_DTRACE
1948 	DTRACE_REQUEST_SHUTDOWN(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
1949 #endif /* HAVE_DTRACE */
1950 }
1951 /* }}} */
1952 
1953 /* {{{ php_com_initialize
1954  */
php_com_initialize(void)1955 PHPAPI void php_com_initialize(void)
1956 {
1957 #ifdef PHP_WIN32
1958 	if (!PG(com_initialized)) {
1959 		if (CoInitialize(NULL) == S_OK) {
1960 			PG(com_initialized) = 1;
1961 		}
1962 	}
1963 #endif
1964 }
1965 /* }}} */
1966 
1967 /* {{{ php_output_wrapper
1968  */
php_output_wrapper(const char * str,size_t str_length)1969 static size_t php_output_wrapper(const char *str, size_t str_length)
1970 {
1971 	return php_output_write(str, str_length);
1972 }
1973 /* }}} */
1974 
1975 #ifdef ZTS
1976 /* {{{ core_globals_ctor
1977  */
core_globals_ctor(php_core_globals * core_globals)1978 static void core_globals_ctor(php_core_globals *core_globals)
1979 {
1980 	memset(core_globals, 0, sizeof(*core_globals));
1981 	php_startup_ticks();
1982 }
1983 /* }}} */
1984 #endif
1985 
1986 /* {{{ core_globals_dtor
1987  */
core_globals_dtor(php_core_globals * core_globals)1988 static void core_globals_dtor(php_core_globals *core_globals)
1989 {
1990 	if (core_globals->last_error_message) {
1991 		free(core_globals->last_error_message);
1992 	}
1993 	if (core_globals->last_error_file) {
1994 		free(core_globals->last_error_file);
1995 	}
1996 	if (core_globals->disable_functions) {
1997 		free(core_globals->disable_functions);
1998 	}
1999 	if (core_globals->disable_classes) {
2000 		free(core_globals->disable_classes);
2001 	}
2002 	if (core_globals->php_binary) {
2003 		free(core_globals->php_binary);
2004 	}
2005 
2006 	php_shutdown_ticks();
2007 }
2008 /* }}} */
2009 
PHP_MINFO_FUNCTION(php_core)2010 PHP_MINFO_FUNCTION(php_core) { /* {{{ */
2011 	php_info_print_table_start();
2012 	php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2013 	php_info_print_table_end();
2014 	DISPLAY_INI_ENTRIES();
2015 }
2016 /* }}} */
2017 
2018 /* {{{ php_register_extensions
2019  */
php_register_extensions(zend_module_entry ** ptr,int count)2020 int php_register_extensions(zend_module_entry **ptr, int count)
2021 {
2022 	zend_module_entry **end = ptr + count;
2023 
2024 	while (ptr < end) {
2025 		if (*ptr) {
2026 			if (zend_register_internal_module(*ptr)==NULL) {
2027 				return FAILURE;
2028 			}
2029 		}
2030 		ptr++;
2031 	}
2032 	return SUCCESS;
2033 }
2034 
2035 /* A very long time ago php_module_startup() was refactored in a way
2036  * which broke calling it with more than one additional module.
2037  * This alternative to php_register_extensions() works around that
2038  * by walking the shallower structure.
2039  *
2040  * See algo: https://bugs.php.net/bug.php?id=63159
2041  */
php_register_extensions_bc(zend_module_entry * ptr,int count)2042 static int php_register_extensions_bc(zend_module_entry *ptr, int count)
2043 {
2044 	while (count--) {
2045 		if (zend_register_internal_module(ptr++) == NULL) {
2046 			return FAILURE;
2047  		}
2048 	}
2049 	return SUCCESS;
2050 }
2051 /* }}} */
2052 
2053 #ifdef PHP_WIN32
2054 static _invalid_parameter_handler old_invalid_parameter_handler;
2055 
dummy_invalid_parameter_handler(const wchar_t * expression,const wchar_t * function,const wchar_t * file,unsigned int line,uintptr_t pEwserved)2056 void dummy_invalid_parameter_handler(
2057 		const wchar_t *expression,
2058 		const wchar_t *function,
2059 		const wchar_t *file,
2060 		unsigned int   line,
2061 		uintptr_t      pEwserved)
2062 {
2063 	static int called = 0;
2064 	char buf[1024];
2065 	int len;
2066 
2067 	if (!called) {
2068 			if(PG(windows_show_crt_warning)) {
2069 			called = 1;
2070 			if (function) {
2071 				if (file) {
2072 					len = _snprintf(buf, sizeof(buf)-1, "Invalid parameter detected in CRT function '%ws' (%ws:%u)", function, file, line);
2073 				} else {
2074 					len = _snprintf(buf, sizeof(buf)-1, "Invalid parameter detected in CRT function '%ws'", function);
2075 				}
2076 			} else {
2077 				len = _snprintf(buf, sizeof(buf)-1, "Invalid CRT parameter detected (function not known)");
2078 			}
2079 			zend_error(E_WARNING, "%s", buf);
2080 			called = 0;
2081 		}
2082 	}
2083 }
2084 #endif
2085 
2086 /* {{{ php_module_startup
2087  */
php_module_startup(sapi_module_struct * sf,zend_module_entry * additional_modules,uint32_t num_additional_modules)2088 int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint32_t num_additional_modules)
2089 {
2090 	zend_utility_functions zuf;
2091 	zend_utility_values zuv;
2092 	int retval = SUCCESS, module_number=0;	/* for REGISTER_INI_ENTRIES() */
2093 	char *php_os;
2094 	zend_module_entry *module;
2095 
2096 #ifdef PHP_WIN32
2097 	WORD wVersionRequested = MAKEWORD(2, 0);
2098 	WSADATA wsaData;
2099 
2100 	php_os = "WINNT";
2101 
2102 	old_invalid_parameter_handler =
2103 		_set_invalid_parameter_handler(dummy_invalid_parameter_handler);
2104 	if (old_invalid_parameter_handler != NULL) {
2105 		_set_invalid_parameter_handler(old_invalid_parameter_handler);
2106 	}
2107 
2108 	/* Disable the message box for assertions.*/
2109 	_CrtSetReportMode(_CRT_ASSERT, 0);
2110 #else
2111 	php_os = PHP_OS;
2112 #endif
2113 
2114 #ifdef ZTS
2115 	(void)ts_resource(0);
2116 #endif
2117 
2118 #ifdef PHP_WIN32
2119 	if (!php_win32_init_random_bytes()) {
2120 		fprintf(stderr, "\ncrypt algorithm provider initialization failed\n");
2121 		return FAILURE;
2122 	}
2123 #endif
2124 
2125 	module_shutdown = 0;
2126 	module_startup = 1;
2127 	sapi_initialize_empty_request();
2128 	sapi_activate();
2129 
2130 	if (module_initialized) {
2131 		return SUCCESS;
2132 	}
2133 
2134 	sapi_module = *sf;
2135 
2136 	php_output_startup();
2137 
2138 #ifdef ZTS
2139 	ts_allocate_id(&core_globals_id, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor);
2140 #ifdef PHP_WIN32
2141 	ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor, (ts_allocate_dtor) php_win32_core_globals_dtor);
2142 #endif
2143 #else
2144 	memset(&core_globals, 0, sizeof(core_globals));
2145 	php_startup_ticks();
2146 #endif
2147 	gc_globals_ctor();
2148 
2149 	zuf.error_function = php_error_cb;
2150 	zuf.printf_function = php_printf;
2151 	zuf.write_function = php_output_wrapper;
2152 	zuf.fopen_function = php_fopen_wrapper_for_zend;
2153 	zuf.message_handler = php_message_handler_for_zend;
2154 	zuf.get_configuration_directive = php_get_configuration_directive_for_zend;
2155 	zuf.ticks_function = php_run_ticks;
2156 	zuf.on_timeout = php_on_timeout;
2157 	zuf.stream_open_function = php_stream_open_for_zend;
2158 	zuf.printf_to_smart_string_function = php_printf_to_smart_string;
2159 	zuf.printf_to_smart_str_function = php_printf_to_smart_str;
2160 	zuf.getenv_function = sapi_getenv;
2161 	zuf.resolve_path_function = php_resolve_path_for_zend;
2162 	zend_startup(&zuf, NULL);
2163 
2164 #if HAVE_SETLOCALE
2165 	setlocale(LC_CTYPE, "");
2166 	zend_update_current_locale();
2167 #endif
2168 
2169 #if HAVE_TZSET
2170 	tzset();
2171 #endif
2172 
2173 #ifdef PHP_WIN32
2174 	/* start up winsock services */
2175 	if (WSAStartup(wVersionRequested, &wsaData) != 0) {
2176 		php_printf("\nwinsock.dll unusable. %d\n", WSAGetLastError());
2177 		return FAILURE;
2178 	}
2179 #endif
2180 
2181 	le_index_ptr = zend_register_list_destructors_ex(NULL, NULL, "index pointer", 0);
2182 
2183 	/* Register constants */
2184 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_VERSION", PHP_VERSION, sizeof(PHP_VERSION)-1, CONST_PERSISTENT | CONST_CS);
2185 	REGISTER_MAIN_LONG_CONSTANT("PHP_MAJOR_VERSION", PHP_MAJOR_VERSION, CONST_PERSISTENT | CONST_CS);
2186 	REGISTER_MAIN_LONG_CONSTANT("PHP_MINOR_VERSION", PHP_MINOR_VERSION, CONST_PERSISTENT | CONST_CS);
2187 	REGISTER_MAIN_LONG_CONSTANT("PHP_RELEASE_VERSION", PHP_RELEASE_VERSION, CONST_PERSISTENT | CONST_CS);
2188 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_EXTRA_VERSION", PHP_EXTRA_VERSION, sizeof(PHP_EXTRA_VERSION) - 1, CONST_PERSISTENT | CONST_CS);
2189 	REGISTER_MAIN_LONG_CONSTANT("PHP_VERSION_ID", PHP_VERSION_ID, CONST_PERSISTENT | CONST_CS);
2190 #ifdef ZTS
2191 	REGISTER_MAIN_LONG_CONSTANT("PHP_ZTS", 1, CONST_PERSISTENT | CONST_CS);
2192 #else
2193 	REGISTER_MAIN_LONG_CONSTANT("PHP_ZTS", 0, CONST_PERSISTENT | CONST_CS);
2194 #endif
2195 	REGISTER_MAIN_LONG_CONSTANT("PHP_DEBUG", PHP_DEBUG, CONST_PERSISTENT | CONST_CS);
2196 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_OS", php_os, strlen(php_os), CONST_PERSISTENT | CONST_CS);
2197 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_OS_FAMILY", PHP_OS_FAMILY, sizeof(PHP_OS_FAMILY)-1, CONST_PERSISTENT | CONST_CS);
2198 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_SAPI", sapi_module.name, strlen(sapi_module.name), CONST_PERSISTENT | CONST_CS);
2199 	REGISTER_MAIN_STRINGL_CONSTANT("DEFAULT_INCLUDE_PATH", PHP_INCLUDE_PATH, sizeof(PHP_INCLUDE_PATH)-1, CONST_PERSISTENT | CONST_CS);
2200 	REGISTER_MAIN_STRINGL_CONSTANT("PEAR_INSTALL_DIR", PEAR_INSTALLDIR, sizeof(PEAR_INSTALLDIR)-1, CONST_PERSISTENT | CONST_CS);
2201 	REGISTER_MAIN_STRINGL_CONSTANT("PEAR_EXTENSION_DIR", PHP_EXTENSION_DIR, sizeof(PHP_EXTENSION_DIR)-1, CONST_PERSISTENT | CONST_CS);
2202 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_EXTENSION_DIR", PHP_EXTENSION_DIR, sizeof(PHP_EXTENSION_DIR)-1, CONST_PERSISTENT | CONST_CS);
2203 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_PREFIX", PHP_PREFIX, sizeof(PHP_PREFIX)-1, CONST_PERSISTENT | CONST_CS);
2204 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINDIR", PHP_BINDIR, sizeof(PHP_BINDIR)-1, CONST_PERSISTENT | CONST_CS);
2205 #ifndef PHP_WIN32
2206 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_MANDIR", PHP_MANDIR, sizeof(PHP_MANDIR)-1, CONST_PERSISTENT | CONST_CS);
2207 #endif
2208 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_LIBDIR", PHP_LIBDIR, sizeof(PHP_LIBDIR)-1, CONST_PERSISTENT | CONST_CS);
2209 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_DATADIR", PHP_DATADIR, sizeof(PHP_DATADIR)-1, CONST_PERSISTENT | CONST_CS);
2210 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_SYSCONFDIR", PHP_SYSCONFDIR, sizeof(PHP_SYSCONFDIR)-1, CONST_PERSISTENT | CONST_CS);
2211 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_LOCALSTATEDIR", PHP_LOCALSTATEDIR, sizeof(PHP_LOCALSTATEDIR)-1, CONST_PERSISTENT | CONST_CS);
2212 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS);
2213 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_SCAN_DIR", PHP_CONFIG_FILE_SCAN_DIR, sizeof(PHP_CONFIG_FILE_SCAN_DIR)-1, CONST_PERSISTENT | CONST_CS);
2214 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
2215 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
2216 	REGISTER_MAIN_LONG_CONSTANT("PHP_MAXPATHLEN", MAXPATHLEN, CONST_PERSISTENT | CONST_CS);
2217 	REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", ZEND_LONG_MAX, CONST_PERSISTENT | CONST_CS);
2218 	REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MIN", ZEND_LONG_MIN, CONST_PERSISTENT | CONST_CS);
2219 	REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", SIZEOF_ZEND_LONG, CONST_PERSISTENT | CONST_CS);
2220 	REGISTER_MAIN_LONG_CONSTANT("PHP_FD_SETSIZE", FD_SETSIZE, CONST_PERSISTENT | CONST_CS);
2221 	REGISTER_MAIN_LONG_CONSTANT("PHP_FLOAT_DIG", DBL_DIG, CONST_PERSISTENT | CONST_CS);
2222 	REGISTER_MAIN_DOUBLE_CONSTANT("PHP_FLOAT_EPSILON", DBL_EPSILON, CONST_PERSISTENT | CONST_CS);
2223 	REGISTER_MAIN_DOUBLE_CONSTANT("PHP_FLOAT_MAX", DBL_MAX, CONST_PERSISTENT | CONST_CS);
2224 	REGISTER_MAIN_DOUBLE_CONSTANT("PHP_FLOAT_MIN", DBL_MIN, CONST_PERSISTENT | CONST_CS);
2225 
2226 #ifdef PHP_WIN32
2227 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_MAJOR",      EG(windows_version_info).dwMajorVersion, CONST_PERSISTENT | CONST_CS);
2228 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_MINOR",      EG(windows_version_info).dwMinorVersion, CONST_PERSISTENT | CONST_CS);
2229 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_BUILD",      EG(windows_version_info).dwBuildNumber, CONST_PERSISTENT | CONST_CS);
2230 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_PLATFORM",   EG(windows_version_info).dwPlatformId, CONST_PERSISTENT | CONST_CS);
2231 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_SP_MAJOR",   EG(windows_version_info).wServicePackMajor, CONST_PERSISTENT | CONST_CS);
2232 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_SP_MINOR",   EG(windows_version_info).wServicePackMinor, CONST_PERSISTENT | CONST_CS);
2233 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_SUITEMASK",  EG(windows_version_info).wSuiteMask, CONST_PERSISTENT | CONST_CS);
2234 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_PRODUCTTYPE", EG(windows_version_info).wProductType, CONST_PERSISTENT | CONST_CS);
2235 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_NT_DOMAIN_CONTROLLER", VER_NT_DOMAIN_CONTROLLER, CONST_PERSISTENT | CONST_CS);
2236 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_NT_SERVER", VER_NT_SERVER, CONST_PERSISTENT | CONST_CS);
2237 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_NT_WORKSTATION", VER_NT_WORKSTATION, CONST_PERSISTENT | CONST_CS);
2238 #endif
2239 
2240 	php_binary_init();
2241 	if (PG(php_binary)) {
2242 		REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY", PG(php_binary), strlen(PG(php_binary)), CONST_PERSISTENT | CONST_CS);
2243 	} else {
2244 		REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY", "", 0, CONST_PERSISTENT | CONST_CS);
2245 	}
2246 
2247 	php_output_register_constants();
2248 	php_rfc1867_register_constants();
2249 
2250 	/* this will read in php.ini, set up the configuration parameters,
2251 	   load zend extensions and register php function extensions
2252 	   to be loaded later */
2253 	if (php_init_config() == FAILURE) {
2254 		return FAILURE;
2255 	}
2256 
2257 	/* Register PHP core ini entries */
2258 	REGISTER_INI_ENTRIES();
2259 
2260 	/* Register Zend ini entries */
2261 	zend_register_standard_ini_entries();
2262 
2263 #ifdef ZEND_WIN32
2264 	/* Until the current ini values was setup, the current cp is 65001.
2265 		If the actual ini vaues are different, some stuff needs to be updated.
2266 		It concerns at least main_cwd_state and there might be more. As we're
2267 		still in the startup phase, lets use the chance and reinit the relevant
2268 		item according to the current codepage. Still, if ini_set() is used
2269 		later on, a more intelligent way to update such stuff is needed.
2270 		Startup/shutdown routines could involve touching globals and thus
2271 		can't always be used on demand. */
2272 	if (!php_win32_cp_use_unicode()) {
2273 		virtual_cwd_main_cwd_init(1);
2274 	}
2275 #endif
2276 
2277 	/* Disable realpath cache if an open_basedir is set */
2278 	if (PG(open_basedir) && *PG(open_basedir)) {
2279 		CWDG(realpath_cache_size_limit) = 0;
2280 	}
2281 
2282 	/* initialize stream wrappers registry
2283 	 * (this uses configuration parameters from php.ini)
2284 	 */
2285 	if (php_init_stream_wrappers(module_number) == FAILURE)	{
2286 		php_printf("PHP:  Unable to initialize stream url wrappers.\n");
2287 		return FAILURE;
2288 	}
2289 
2290 	zuv.html_errors = 1;
2291 	zuv.import_use_extension = ".php";
2292 	zuv.import_use_extension_length = (uint32_t)strlen(zuv.import_use_extension);
2293 	php_startup_auto_globals();
2294 	zend_set_utility_values(&zuv);
2295 	php_startup_sapi_content_types();
2296 
2297 	/* startup extensions statically compiled in */
2298 	if (php_register_internal_extensions_func() == FAILURE) {
2299 		php_printf("Unable to start builtin modules\n");
2300 		return FAILURE;
2301 	}
2302 
2303 	/* start additional PHP extensions */
2304 	php_register_extensions_bc(additional_modules, num_additional_modules);
2305 
2306 	/* load and startup extensions compiled as shared objects (aka DLLs)
2307 	   as requested by php.ini entries
2308 	   these are loaded after initialization of internal extensions
2309 	   as extensions *might* rely on things from ext/standard
2310 	   which is always an internal extension and to be initialized
2311 	   ahead of all other internals
2312 	 */
2313 	php_ini_register_extensions();
2314 	zend_startup_modules();
2315 
2316 	/* start Zend extensions */
2317 	zend_startup_extensions();
2318 
2319 	zend_collect_module_handlers();
2320 
2321 	/* register additional functions */
2322 	if (sapi_module.additional_functions) {
2323 		if ((module = zend_hash_str_find_ptr(&module_registry, "standard", sizeof("standard")-1)) != NULL) {
2324 			EG(current_module) = module;
2325 			zend_register_functions(NULL, sapi_module.additional_functions, NULL, MODULE_PERSISTENT);
2326 			EG(current_module) = NULL;
2327 		}
2328 	}
2329 
2330 	/* disable certain classes and functions as requested by php.ini */
2331 	php_disable_functions();
2332 	php_disable_classes();
2333 
2334 	/* make core report what it should */
2335 	if ((module = zend_hash_str_find_ptr(&module_registry, "core", sizeof("core")-1)) != NULL) {
2336 		module->version = PHP_VERSION;
2337 		module->info_func = PHP_MINFO(php_core);
2338 	}
2339 
2340 	zend_post_startup();
2341 
2342 	module_initialized = 1;
2343 
2344 	/* Check for deprecated directives */
2345 	/* NOTE: If you add anything here, remember to add it to Makefile.global! */
2346 	{
2347 		struct {
2348 			const long error_level;
2349 			const char *phrase;
2350 			const char *directives[17]; /* Remember to change this if the number of directives change */
2351 		} directives[2] = {
2352 			{
2353 				E_DEPRECATED,
2354 				"Directive '%s' is deprecated",
2355 				{
2356 					"track_errors",
2357 					NULL
2358 				}
2359 			},
2360 			{
2361 				E_CORE_ERROR,
2362 				"Directive '%s' is no longer available in PHP",
2363 				{
2364 					"allow_call_time_pass_reference",
2365 					"asp_tags",
2366 					"define_syslog_variables",
2367 					"highlight.bg",
2368 					"magic_quotes_gpc",
2369 					"magic_quotes_runtime",
2370 					"magic_quotes_sybase",
2371 					"register_globals",
2372 					"register_long_arrays",
2373 					"safe_mode",
2374 					"safe_mode_gid",
2375 					"safe_mode_include_dir",
2376 					"safe_mode_exec_dir",
2377 					"safe_mode_allowed_env_vars",
2378 					"safe_mode_protected_env_vars",
2379 					"zend.ze1_compatibility_mode",
2380 					NULL
2381 				}
2382 			}
2383 		};
2384 
2385 		unsigned int i;
2386 
2387 		zend_try {
2388 			/* 2 = Count of deprecation structs */
2389 			for (i = 0; i < 2; i++) {
2390 				const char **p = directives[i].directives;
2391 
2392 				while(*p) {
2393 					zend_long value;
2394 
2395 					if (cfg_get_long((char*)*p, &value) == SUCCESS && value) {
2396 						zend_error(directives[i].error_level, directives[i].phrase, *p);
2397 					}
2398 
2399 					++p;
2400 				}
2401 			}
2402 		} zend_catch {
2403 			retval = FAILURE;
2404 		} zend_end_try();
2405 	}
2406 
2407 	virtual_cwd_deactivate();
2408 
2409 	sapi_deactivate();
2410 	module_startup = 0;
2411 
2412 	shutdown_memory_manager(1, 0);
2413  	virtual_cwd_activate();
2414 
2415 	zend_interned_strings_switch_storage();
2416 
2417 	/* we're done */
2418 	return retval;
2419 }
2420 /* }}} */
2421 
php_module_shutdown_for_exec(void)2422 void php_module_shutdown_for_exec(void)
2423 {
2424 	/* used to close fd's in the range 3.255 here, but it's problematic */
2425 }
2426 
2427 /* {{{ php_module_shutdown_wrapper
2428  */
php_module_shutdown_wrapper(sapi_module_struct * sapi_globals)2429 int php_module_shutdown_wrapper(sapi_module_struct *sapi_globals)
2430 {
2431 	php_module_shutdown();
2432 	return SUCCESS;
2433 }
2434 /* }}} */
2435 
2436 /* {{{ php_module_shutdown
2437  */
php_module_shutdown(void)2438 void php_module_shutdown(void)
2439 {
2440 	int module_number=0;	/* for UNREGISTER_INI_ENTRIES() */
2441 
2442 	module_shutdown = 1;
2443 
2444 	if (!module_initialized) {
2445 		return;
2446 	}
2447 
2448 #ifdef ZTS
2449 	ts_free_worker_threads();
2450 #endif
2451 
2452 #ifdef PHP_WIN32
2453 	(void)php_win32_shutdown_random_bytes();
2454 #endif
2455 
2456 	sapi_flush();
2457 
2458 	zend_shutdown();
2459 
2460 #ifdef PHP_WIN32
2461 	/*close winsock */
2462 	WSACleanup();
2463 #endif
2464 
2465 	/* Destroys filter & transport registries too */
2466 	php_shutdown_stream_wrappers(module_number);
2467 
2468 	UNREGISTER_INI_ENTRIES();
2469 
2470 	/* close down the ini config */
2471 	php_shutdown_config();
2472 
2473 #ifndef ZTS
2474 	zend_ini_shutdown();
2475 	shutdown_memory_manager(CG(unclean_shutdown), 1);
2476 #else
2477 	zend_ini_global_shutdown();
2478 #endif
2479 
2480 	php_output_shutdown();
2481 
2482 #ifndef ZTS
2483 	zend_interned_strings_dtor();
2484 #endif
2485 
2486 	module_initialized = 0;
2487 
2488 #ifndef ZTS
2489 	core_globals_dtor(&core_globals);
2490 	gc_globals_dtor();
2491 #else
2492 	ts_free_id(core_globals_id);
2493 #endif
2494 
2495 #ifdef PHP_WIN32
2496 	if (old_invalid_parameter_handler == NULL) {
2497 		_set_invalid_parameter_handler(old_invalid_parameter_handler);
2498 	}
2499 #endif
2500 }
2501 /* }}} */
2502 
2503 /* {{{ php_execute_script
2504  */
php_execute_script(zend_file_handle * primary_file)2505 PHPAPI int php_execute_script(zend_file_handle *primary_file)
2506 {
2507 	zend_file_handle *prepend_file_p, *append_file_p;
2508 	zend_file_handle prepend_file = {{0}, NULL, NULL, 0, 0}, append_file = {{0}, NULL, NULL, 0, 0};
2509 #if HAVE_BROKEN_GETCWD
2510 	volatile int old_cwd_fd = -1;
2511 #else
2512 	char *old_cwd;
2513 	ALLOCA_FLAG(use_heap)
2514 #endif
2515 	int retval = 0;
2516 
2517 	EG(exit_status) = 0;
2518 #ifndef HAVE_BROKEN_GETCWD
2519 # define OLD_CWD_SIZE 4096
2520 	old_cwd = do_alloca(OLD_CWD_SIZE, use_heap);
2521 	old_cwd[0] = '\0';
2522 #endif
2523 
2524 	zend_try {
2525 		char realfile[MAXPATHLEN];
2526 
2527 #ifdef PHP_WIN32
2528 		if(primary_file->filename) {
2529 			UpdateIniFromRegistry((char*)primary_file->filename);
2530 		}
2531 #endif
2532 
2533 		PG(during_request_startup) = 0;
2534 
2535 		if (primary_file->filename && !(SG(options) & SAPI_OPTION_NO_CHDIR)) {
2536 #if HAVE_BROKEN_GETCWD
2537 			/* this looks nasty to me */
2538 			old_cwd_fd = open(".", 0);
2539 #else
2540 			php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1));
2541 #endif
2542 			VCWD_CHDIR_FILE(primary_file->filename);
2543 		}
2544 
2545  		/* Only lookup the real file path and add it to the included_files list if already opened
2546 		 *   otherwise it will get opened and added to the included_files list in zend_execute_scripts
2547 		 */
2548  		if (primary_file->filename &&
2549  		    strcmp("Standard input code", primary_file->filename) &&
2550  			primary_file->opened_path == NULL &&
2551  			primary_file->type != ZEND_HANDLE_FILENAME
2552 		) {
2553 			if (expand_filepath(primary_file->filename, realfile)) {
2554 				primary_file->opened_path = zend_string_init(realfile, strlen(realfile), 0);
2555 				zend_hash_add_empty_element(&EG(included_files), primary_file->opened_path);
2556 			}
2557 		}
2558 
2559 		if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) {
2560 			prepend_file.filename = PG(auto_prepend_file);
2561 			prepend_file.opened_path = NULL;
2562 			prepend_file.free_filename = 0;
2563 			prepend_file.type = ZEND_HANDLE_FILENAME;
2564 			prepend_file_p = &prepend_file;
2565 		} else {
2566 			prepend_file_p = NULL;
2567 		}
2568 
2569 		if (PG(auto_append_file) && PG(auto_append_file)[0]) {
2570 			append_file.filename = PG(auto_append_file);
2571 			append_file.opened_path = NULL;
2572 			append_file.free_filename = 0;
2573 			append_file.type = ZEND_HANDLE_FILENAME;
2574 			append_file_p = &append_file;
2575 		} else {
2576 			append_file_p = NULL;
2577 		}
2578 		if (PG(max_input_time) != -1) {
2579 #ifdef PHP_WIN32
2580 			zend_unset_timeout();
2581 #endif
2582 			zend_set_timeout(INI_INT("max_execution_time"), 0);
2583 		}
2584 
2585 		/*
2586 		   If cli primary file has shabang line and there is a prepend file,
2587 		   the `start_lineno` will be used by prepend file but not primary file,
2588 		   save it and restore after prepend file been executed.
2589 		 */
2590 		if (CG(start_lineno) && prepend_file_p) {
2591 			int orig_start_lineno = CG(start_lineno);
2592 
2593 			CG(start_lineno) = 0;
2594 			if (zend_execute_scripts(ZEND_REQUIRE, NULL, 1, prepend_file_p) == SUCCESS) {
2595 				CG(start_lineno) = orig_start_lineno;
2596 				retval = (zend_execute_scripts(ZEND_REQUIRE, NULL, 2, primary_file, append_file_p) == SUCCESS);
2597 			}
2598 		} else {
2599 			retval = (zend_execute_scripts(ZEND_REQUIRE, NULL, 3, prepend_file_p, primary_file, append_file_p) == SUCCESS);
2600 		}
2601 	} zend_end_try();
2602 
2603 	if (EG(exception)) {
2604 		zend_try {
2605 			zend_exception_error(EG(exception), E_ERROR);
2606 		} zend_end_try();
2607 	}
2608 
2609 #if HAVE_BROKEN_GETCWD
2610 	if (old_cwd_fd != -1) {
2611 		fchdir(old_cwd_fd);
2612 		close(old_cwd_fd);
2613 	}
2614 #else
2615 	if (old_cwd[0] != '\0') {
2616 		php_ignore_value(VCWD_CHDIR(old_cwd));
2617 	}
2618 	free_alloca(old_cwd, use_heap);
2619 #endif
2620 	return retval;
2621 }
2622 /* }}} */
2623 
2624 /* {{{ php_execute_simple_script
2625  */
php_execute_simple_script(zend_file_handle * primary_file,zval * ret)2626 PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval *ret)
2627 {
2628 	char *old_cwd;
2629 	ALLOCA_FLAG(use_heap)
2630 
2631 	EG(exit_status) = 0;
2632 #define OLD_CWD_SIZE 4096
2633 	old_cwd = do_alloca(OLD_CWD_SIZE, use_heap);
2634 	old_cwd[0] = '\0';
2635 
2636 	zend_try {
2637 #ifdef PHP_WIN32
2638 		if(primary_file->filename) {
2639 			UpdateIniFromRegistry((char*)primary_file->filename);
2640 		}
2641 #endif
2642 
2643 		PG(during_request_startup) = 0;
2644 
2645 		if (primary_file->filename && !(SG(options) & SAPI_OPTION_NO_CHDIR)) {
2646 			php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1));
2647 			VCWD_CHDIR_FILE(primary_file->filename);
2648 		}
2649 		zend_execute_scripts(ZEND_REQUIRE, ret, 1, primary_file);
2650 	} zend_end_try();
2651 
2652 	if (old_cwd[0] != '\0') {
2653 		php_ignore_value(VCWD_CHDIR(old_cwd));
2654 	}
2655 
2656 	free_alloca(old_cwd, use_heap);
2657 	return EG(exit_status);
2658 }
2659 /* }}} */
2660 
2661 /* {{{ php_handle_aborted_connection
2662  */
php_handle_aborted_connection(void)2663 PHPAPI void php_handle_aborted_connection(void)
2664 {
2665 
2666 	PG(connection_status) = PHP_CONNECTION_ABORTED;
2667 	php_output_set_status(PHP_OUTPUT_DISABLED);
2668 
2669 	if (!PG(ignore_user_abort)) {
2670 		zend_bailout();
2671 	}
2672 }
2673 /* }}} */
2674 
2675 /* {{{ php_handle_auth_data
2676  */
php_handle_auth_data(const char * auth)2677 PHPAPI int php_handle_auth_data(const char *auth)
2678 {
2679 	int ret = -1;
2680 
2681 	if (auth && auth[0] != '\0' && strncmp(auth, "Basic ", 6) == 0) {
2682 		char *pass;
2683 		zend_string *user;
2684 
2685 		user = php_base64_decode((const unsigned char*)auth + 6, strlen(auth) - 6);
2686 		if (user) {
2687 			pass = strchr(ZSTR_VAL(user), ':');
2688 			if (pass) {
2689 				*pass++ = '\0';
2690 				SG(request_info).auth_user = estrndup(ZSTR_VAL(user), ZSTR_LEN(user));
2691 				SG(request_info).auth_password = estrdup(pass);
2692 				ret = 0;
2693 			}
2694 			zend_string_free(user);
2695 		}
2696 	}
2697 
2698 	if (ret == -1) {
2699 		SG(request_info).auth_user = SG(request_info).auth_password = NULL;
2700 	} else {
2701 		SG(request_info).auth_digest = NULL;
2702 	}
2703 
2704 	if (ret == -1 && auth && auth[0] != '\0' && strncmp(auth, "Digest ", 7) == 0) {
2705 		SG(request_info).auth_digest = estrdup(auth + 7);
2706 		ret = 0;
2707 	}
2708 
2709 	if (ret == -1) {
2710 		SG(request_info).auth_digest = NULL;
2711 	}
2712 
2713 	return ret;
2714 }
2715 /* }}} */
2716 
2717 /* {{{ php_lint_script
2718  */
php_lint_script(zend_file_handle * file)2719 PHPAPI int php_lint_script(zend_file_handle *file)
2720 {
2721 	zend_op_array *op_array;
2722 	int retval = FAILURE;
2723 
2724 	zend_try {
2725 		op_array = zend_compile_file(file, ZEND_INCLUDE);
2726 		zend_destroy_file_handle(file);
2727 
2728 		if (op_array) {
2729 			destroy_op_array(op_array);
2730 			efree(op_array);
2731 			retval = SUCCESS;
2732 		}
2733 	} zend_end_try();
2734 	if (EG(exception)) {
2735 		zend_exception_error(EG(exception), E_ERROR);
2736 	}
2737 
2738 	return retval;
2739 }
2740 /* }}} */
2741 
2742 /*
2743  * Local variables:
2744  * tab-width: 4
2745  * c-basic-offset: 4
2746  * End:
2747  * vim600: sw=4 ts=4 fdm=marker
2748  * vim<600: sw=4 ts=4
2749  */
2750