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