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