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