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 *)malloc(MAXPATHLEN);
356 	if (binary_location && GetModuleFileName(0, binary_location, MAXPATHLEN) == 0) {
357 		free(binary_location);
358 		PG(php_binary) = NULL;
359 	}
360 #else
361 	if (sapi_module.executable_location) {
362 		binary_location = (char *)malloc(MAXPATHLEN);
363 		if (binary_location && !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 				free(binary_location);
387 				binary_location = NULL;
388 			}
389 		} else if (!VCWD_REALPATH(sapi_module.executable_location, binary_location) || VCWD_ACCESS(binary_location, X_OK)) {
390 			free(binary_location);
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 
755 	STD_PHP_INI_BOOLEAN("allow_url_fopen",		"1",		PHP_INI_SYSTEM,		OnUpdateBool,		allow_url_fopen,		php_core_globals,		core_globals)
756 	STD_PHP_INI_BOOLEAN("allow_url_include",	"0",		PHP_INI_SYSTEM,		OnUpdateBool,		allow_url_include,		php_core_globals,		core_globals)
757 	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)
758 
759 	STD_PHP_INI_ENTRY("realpath_cache_size",	"4096K",	PHP_INI_SYSTEM,		OnUpdateLong,	realpath_cache_size_limit,	virtual_cwd_globals,	cwd_globals)
760 	STD_PHP_INI_ENTRY("realpath_cache_ttl",		"120",		PHP_INI_SYSTEM,		OnUpdateLong,	realpath_cache_ttl,			virtual_cwd_globals,	cwd_globals)
761 
762 	STD_PHP_INI_ENTRY("user_ini.filename",		".user.ini",	PHP_INI_SYSTEM,		OnUpdateString,		user_ini_filename,	php_core_globals,		core_globals)
763 	STD_PHP_INI_ENTRY("user_ini.cache_ttl",		"300",			PHP_INI_SYSTEM,		OnUpdateLong,		user_ini_cache_ttl,	php_core_globals,		core_globals)
764 	STD_PHP_INI_ENTRY("hard_timeout",			"2",			PHP_INI_SYSTEM,		OnUpdateLong,		hard_timeout,		zend_executor_globals,	executor_globals)
765 #ifdef PHP_WIN32
766 	STD_PHP_INI_BOOLEAN("windows.show_crt_warning",		"0",		PHP_INI_ALL,		OnUpdateBool,			windows_show_crt_warning,			php_core_globals,	core_globals)
767 #endif
768 	STD_PHP_INI_ENTRY("syslog.facility",		"LOG_USER",		PHP_INI_SYSTEM,		OnSetFacility,		syslog_facility,	php_core_globals,		core_globals)
769 	STD_PHP_INI_ENTRY("syslog.ident",		"php",			PHP_INI_SYSTEM,		OnUpdateString,		syslog_ident,		php_core_globals,		core_globals)
770 	STD_PHP_INI_ENTRY("syslog.filter",		"no-ctrl",		PHP_INI_ALL,		OnSetLogFilter,		syslog_filter,		php_core_globals, 		core_globals)
771 PHP_INI_END()
772 /* }}} */
773 
774 /* True globals (no need for thread safety */
775 /* But don't make them a single int bitfield */
776 static int module_initialized = 0;
777 static int module_startup = 1;
778 static int module_shutdown = 0;
779 
780 /* {{{ php_during_module_startup */
php_during_module_startup(void)781 PHPAPI int php_during_module_startup(void)
782 {
783 	return module_startup;
784 }
785 /* }}} */
786 
787 /* {{{ php_during_module_shutdown */
php_during_module_shutdown(void)788 PHPAPI int php_during_module_shutdown(void)
789 {
790 	return module_shutdown;
791 }
792 /* }}} */
793 
794 /* {{{ php_get_module_initialized */
php_get_module_initialized(void)795 PHPAPI int php_get_module_initialized(void)
796 {
797 	return module_initialized;
798 }
799 /* }}} */
800 
801 /* {{{ php_log_err_with_severity */
php_log_err_with_severity(const char * log_message,int syslog_type_int)802 PHPAPI ZEND_COLD void php_log_err_with_severity(const char *log_message, int syslog_type_int)
803 {
804 	int fd = -1;
805 	time_t error_time;
806 
807 	if (PG(in_error_log)) {
808 		/* prevent recursive invocation */
809 		return;
810 	}
811 	PG(in_error_log) = 1;
812 
813 	/* Try to use the specified logging location. */
814 	if (PG(error_log) != NULL) {
815 #ifdef HAVE_SYSLOG_H
816 		if (!strcmp(PG(error_log), "syslog")) {
817 			php_syslog(syslog_type_int, "%s", log_message);
818 			PG(in_error_log) = 0;
819 			return;
820 		}
821 #endif
822 		fd = VCWD_OPEN_MODE(PG(error_log), O_CREAT | O_APPEND | O_WRONLY, 0644);
823 		if (fd != -1) {
824 			char *tmp;
825 			size_t len;
826 			zend_string *error_time_str;
827 
828 			time(&error_time);
829 #ifdef ZTS
830 			if (!php_during_module_startup()) {
831 				error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1);
832 			} else {
833 				error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 0);
834 			}
835 #else
836 			error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1);
837 #endif
838 			len = spprintf(&tmp, 0, "[%s] %s%s", ZSTR_VAL(error_time_str), log_message, PHP_EOL);
839 #ifdef PHP_WIN32
840 			php_flock(fd, 2);
841 			/* XXX should eventually write in a loop if len > UINT_MAX */
842 			php_ignore_value(write(fd, tmp, (unsigned)len));
843 #else
844 			php_ignore_value(write(fd, tmp, len));
845 #endif
846 			efree(tmp);
847 			zend_string_free(error_time_str);
848 			close(fd);
849 			PG(in_error_log) = 0;
850 			return;
851 		}
852 	}
853 
854 	/* Otherwise fall back to the default logging location, if we have one */
855 
856 	if (sapi_module.log_message) {
857 		sapi_module.log_message(log_message, syslog_type_int);
858 	}
859 	PG(in_error_log) = 0;
860 }
861 /* }}} */
862 
863 /* {{{ php_write
864    wrapper for modules to use PHPWRITE */
php_write(void * buf,size_t size)865 PHPAPI size_t php_write(void *buf, size_t size)
866 {
867 	return PHPWRITE(buf, size);
868 }
869 /* }}} */
870 
871 /* {{{ php_printf */
php_printf(const char * format,...)872 PHPAPI size_t php_printf(const char *format, ...)
873 {
874 	va_list args;
875 	size_t ret;
876 	char *buffer;
877 	size_t size;
878 
879 	va_start(args, format);
880 	size = vspprintf(&buffer, 0, format, args);
881 	ret = PHPWRITE(buffer, size);
882 	efree(buffer);
883 	va_end(args);
884 
885 	return ret;
886 }
887 /* }}} */
888 
889 /* {{{ php_printf_unchecked */
php_printf_unchecked(const char * format,...)890 PHPAPI size_t php_printf_unchecked(const char *format, ...)
891 {
892 	va_list args;
893 	size_t ret;
894 	char *buffer;
895 	size_t size;
896 
897 	va_start(args, format);
898 	size = vspprintf(&buffer, 0, format, args);
899 	ret = PHPWRITE(buffer, size);
900 	efree(buffer);
901 	va_end(args);
902 
903 	return ret;
904 }
905 /* }}} */
906 
escape_html(const char * buffer,size_t buffer_len)907 static zend_string *escape_html(const char *buffer, size_t buffer_len) {
908 	zend_string *result = php_escape_html_entities_ex(
909 		(const unsigned char *) buffer, buffer_len, 0, ENT_COMPAT,
910 		/* charset_hint */ NULL, /* double_encode */ 1, /* quiet */ 1);
911 	if (!result || ZSTR_LEN(result) == 0) {
912 		/* Retry with substituting invalid chars on fail. */
913 		result = php_escape_html_entities_ex(
914 			(const unsigned char *) buffer, buffer_len, 0, ENT_COMPAT | ENT_HTML_SUBSTITUTE_ERRORS,
915 			/* charset_hint */ NULL, /* double_encode */ 1, /* quiet */ 1);
916 	}
917 	return result;
918 }
919 
920 /* {{{ php_verror */
921 /* php_verror is called from php_error_docref<n> functions.
922  * Its purpose is to unify error messages and automatically generate clickable
923  * html error messages if corresponding ini setting (html_errors) is activated.
924  * See: CODING_STANDARDS.md for details.
925  */
php_verror(const char * docref,const char * params,int type,const char * format,va_list args)926 PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int type, const char *format, va_list args)
927 {
928 	zend_string *replace_buffer = NULL, *replace_origin = NULL;
929 	char *buffer = NULL, *docref_buf = NULL, *target = NULL;
930 	char *docref_target = "", *docref_root = "";
931 	char *p;
932 	int buffer_len = 0;
933 	const char *space = "";
934 	const char *class_name = "";
935 	const char *function;
936 	int origin_len;
937 	char *origin;
938 	zend_string *message;
939 	int is_function = 0;
940 
941 	/* get error text into buffer and escape for html if necessary */
942 	buffer_len = (int)vspprintf(&buffer, 0, format, args);
943 
944 	if (PG(html_errors)) {
945 		replace_buffer = escape_html(buffer, buffer_len);
946 		efree(buffer);
947 
948 		if (replace_buffer) {
949 			buffer = ZSTR_VAL(replace_buffer);
950 			buffer_len = (int)ZSTR_LEN(replace_buffer);
951 		} else {
952 			buffer = "";
953 			buffer_len = 0;
954 		}
955 	}
956 
957 	/* which function caused the problem if any at all */
958 	if (php_during_module_startup()) {
959 		function = "PHP Startup";
960 	} else if (php_during_module_shutdown()) {
961 		function = "PHP Shutdown";
962 	} else if (EG(current_execute_data) &&
963 				EG(current_execute_data)->func &&
964 				ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
965 				EG(current_execute_data)->opline &&
966 				EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL
967 	) {
968 		switch (EG(current_execute_data)->opline->extended_value) {
969 			case ZEND_EVAL:
970 				function = "eval";
971 				is_function = 1;
972 				break;
973 			case ZEND_INCLUDE:
974 				function = "include";
975 				is_function = 1;
976 				break;
977 			case ZEND_INCLUDE_ONCE:
978 				function = "include_once";
979 				is_function = 1;
980 				break;
981 			case ZEND_REQUIRE:
982 				function = "require";
983 				is_function = 1;
984 				break;
985 			case ZEND_REQUIRE_ONCE:
986 				function = "require_once";
987 				is_function = 1;
988 				break;
989 			default:
990 				function = "Unknown";
991 		}
992 	} else {
993 		function = get_active_function_name();
994 		if (!function || !strlen(function)) {
995 			function = "Unknown";
996 		} else {
997 			is_function = 1;
998 			class_name = get_active_class_name(&space);
999 		}
1000 	}
1001 
1002 	/* if we still have memory then format the origin */
1003 	if (is_function) {
1004 		origin_len = (int)spprintf(&origin, 0, "%s%s%s(%s)", class_name, space, function, params);
1005 	} else {
1006 		origin_len = (int)spprintf(&origin, 0, "%s", function);
1007 	}
1008 
1009 	if (PG(html_errors)) {
1010 		replace_origin = escape_html(origin, origin_len);
1011 		efree(origin);
1012 		origin = ZSTR_VAL(replace_origin);
1013 	}
1014 
1015 	/* origin and buffer available, so lets come up with the error message */
1016 	if (docref && docref[0] == '#') {
1017 		docref_target = strchr(docref, '#');
1018 		docref = NULL;
1019 	}
1020 
1021 	/* no docref given but function is known (the default) */
1022 	if (!docref && is_function) {
1023 		int doclen;
1024 		while (*function == '_') {
1025 			function++;
1026 		}
1027 		if (space[0] == '\0') {
1028 			doclen = (int)spprintf(&docref_buf, 0, "function.%s", function);
1029 		} else {
1030 			doclen = (int)spprintf(&docref_buf, 0, "%s.%s", class_name, function);
1031 		}
1032 		while((p = strchr(docref_buf, '_')) != NULL) {
1033 			*p = '-';
1034 		}
1035 		docref = php_strtolower(docref_buf, doclen);
1036 	}
1037 
1038 	/* we have a docref for a function AND
1039 	 * - we show errors in html mode AND
1040 	 * - the user wants to see the links
1041 	 */
1042 	if (docref && is_function && PG(html_errors) && strlen(PG(docref_root))) {
1043 		if (strncmp(docref, "http://", 7)) {
1044 			/* We don't have 'http://' so we use docref_root */
1045 
1046 			char *ref;  /* temp copy for duplicated docref */
1047 
1048 			docref_root = PG(docref_root);
1049 
1050 			ref = estrdup(docref);
1051 			if (docref_buf) {
1052 				efree(docref_buf);
1053 			}
1054 			docref_buf = ref;
1055 			/* strip of the target if any */
1056 			p = strrchr(ref, '#');
1057 			if (p) {
1058 				target = estrdup(p);
1059 				if (target) {
1060 					docref_target = target;
1061 					*p = '\0';
1062 				}
1063 			}
1064 			/* add the extension if it is set in ini */
1065 			if (PG(docref_ext) && strlen(PG(docref_ext))) {
1066 				spprintf(&docref_buf, 0, "%s%s", ref, PG(docref_ext));
1067 				efree(ref);
1068 			}
1069 			docref = docref_buf;
1070 		}
1071 		/* display html formatted or only show the additional links */
1072 		if (PG(html_errors)) {
1073 			message = zend_strpprintf(0, "%s [<a href='%s%s%s'>%s</a>]: %s", origin, docref_root, docref, docref_target, docref, buffer);
1074 		} else {
1075 			message = zend_strpprintf(0, "%s [%s%s%s]: %s", origin, docref_root, docref, docref_target, buffer);
1076 		}
1077 		if (target) {
1078 			efree(target);
1079 		}
1080 	} else {
1081 		message = zend_strpprintf(0, "%s: %s", origin, buffer);
1082 	}
1083 	if (replace_origin) {
1084 		zend_string_free(replace_origin);
1085 	} else {
1086 		efree(origin);
1087 	}
1088 	if (docref_buf) {
1089 		efree(docref_buf);
1090 	}
1091 
1092 	if (replace_buffer) {
1093 		zend_string_free(replace_buffer);
1094 	} else {
1095 		efree(buffer);
1096 	}
1097 
1098 	zend_error_zstr(type, message);
1099 	zend_string_release(message);
1100 }
1101 /* }}} */
1102 
1103 /* {{{ php_error_docref */
1104 /* 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,...)1105 PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format, ...)
1106 {
1107 	va_list args;
1108 
1109 	va_start(args, format);
1110 	php_verror(docref, "", type, format, args);
1111 	va_end(args);
1112 }
1113 /* }}} */
1114 
1115 /* {{{ php_error_docref1 */
1116 /* See: CODING_STANDARDS.md for details. */
php_error_docref1(const char * docref,const char * param1,int type,const char * format,...)1117 PHPAPI ZEND_COLD void php_error_docref1(const char *docref, const char *param1, int type, const char *format, ...)
1118 {
1119 	va_list args;
1120 
1121 	va_start(args, format);
1122 	php_verror(docref, param1, type, format, args);
1123 	va_end(args);
1124 }
1125 /* }}} */
1126 
1127 /* {{{ php_error_docref2 */
1128 /* See: CODING_STANDARDS.md for details. */
php_error_docref2(const char * docref,const char * param1,const char * param2,int type,const char * format,...)1129 PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1, const char *param2, int type, const char *format, ...)
1130 {
1131 	char *params;
1132 	va_list args;
1133 
1134 	spprintf(&params, 0, "%s,%s", param1, param2);
1135 	va_start(args, format);
1136 	php_verror(docref, params ? params : "...", type, format, args);
1137 	va_end(args);
1138 	if (params) {
1139 		efree(params);
1140 	}
1141 }
1142 /* }}} */
1143 
1144 #ifdef PHP_WIN32
php_win32_docref1_from_error(DWORD error,const char * param1)1145 PHPAPI ZEND_COLD void php_win32_docref1_from_error(DWORD error, const char *param1) {
1146 	char *buf = php_win32_error_to_msg(error);
1147 	size_t buf_len;
1148 
1149 	buf_len = strlen(buf);
1150 	if (buf_len >= 2) {
1151 		buf[buf_len - 1] = '\0';
1152 		buf[buf_len - 2] = '\0';
1153 	}
1154 	php_error_docref1(NULL, param1, E_WARNING, "%s (code: %lu)", buf, error);
1155 	php_win32_error_msg_free(buf);
1156 }
1157 
php_win32_docref2_from_error(DWORD error,const char * param1,const char * param2)1158 PHPAPI ZEND_COLD void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2) {
1159 	char *buf = php_win32_error_to_msg(error);
1160 	php_error_docref2(NULL, param1, param2, E_WARNING, "%s (code: %lu)", buf, error);
1161 	php_win32_error_msg_free(buf);
1162 }
1163 #endif
1164 
1165 /* {{{ php_html_puts */
php_html_puts(const char * str,size_t size)1166 PHPAPI void php_html_puts(const char *str, size_t size)
1167 {
1168 	zend_html_puts(str, size);
1169 }
1170 /* }}} */
1171 
clear_last_error()1172 static void clear_last_error() {
1173 	if (PG(last_error_message)) {
1174 		zend_string_release(PG(last_error_message));
1175 		PG(last_error_message) = NULL;
1176 	}
1177 	if (PG(last_error_file)) {
1178 		free(PG(last_error_file));
1179 		PG(last_error_file) = NULL;
1180 	}
1181 }
1182 
1183 #if ZEND_DEBUG
1184 /* {{{ 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)1185 static void report_zend_debug_error_notify_cb(int type, const char *error_filename, uint32_t error_lineno, zend_string *message)
1186 {
1187 	if (PG(report_zend_debug)) {
1188 		zend_bool trigger_break;
1189 
1190 		switch (type) {
1191 			case E_ERROR:
1192 			case E_CORE_ERROR:
1193 			case E_COMPILE_ERROR:
1194 			case E_USER_ERROR:
1195 				trigger_break=1;
1196 				break;
1197 			default:
1198 				trigger_break=0;
1199 				break;
1200 		}
1201 
1202 		zend_output_debug_string(trigger_break, "%s(%" PRIu32 ") : %s", error_filename, error_lineno, ZSTR_VAL(message));
1203 	}
1204 }
1205 /* }}} */
1206 #endif
1207 
1208 /* {{{ php_error_cb
1209  extended error handling function */
php_error_cb(int orig_type,const char * error_filename,const uint32_t error_lineno,zend_string * message)1210 static ZEND_COLD void php_error_cb(int orig_type, const char *error_filename, const uint32_t error_lineno, zend_string *message)
1211 {
1212 	zend_bool display;
1213 	int type = orig_type & E_ALL;
1214 
1215 	/* check for repeated errors to be ignored */
1216 	if (PG(ignore_repeated_errors) && PG(last_error_message)) {
1217 		/* no check for PG(last_error_file) is needed since it cannot
1218 		 * be NULL if PG(last_error_message) is not NULL */
1219 		if (!zend_string_equals(PG(last_error_message), message)
1220 			|| (!PG(ignore_repeated_source)
1221 				&& ((PG(last_error_lineno) != (int)error_lineno)
1222 					|| strcmp(PG(last_error_file), error_filename)))) {
1223 			display = 1;
1224 		} else {
1225 			display = 0;
1226 		}
1227 	} else {
1228 		display = 1;
1229 	}
1230 
1231 	/* according to error handling mode, throw exception or show it */
1232 	if (EG(error_handling) == EH_THROW) {
1233 		switch (type) {
1234 			case E_WARNING:
1235 			case E_CORE_WARNING:
1236 			case E_COMPILE_WARNING:
1237 			case E_USER_WARNING:
1238 				/* throw an exception if we are in EH_THROW mode and the type is warning.
1239 				 * fatal errors are real errors and cannot be made exceptions.
1240 				 * exclude deprecated for the sake of BC to old damaged code.
1241 				 * notices are no errors and are not treated as such like E_WARNINGS.
1242 				 * DO NOT overwrite a pending exception.
1243 				 */
1244 				if (!EG(exception)) {
1245 					zend_throw_error_exception(EG(exception_class), message, 0, type);
1246 				}
1247 				return;
1248 			default:
1249 				break;
1250 		}
1251 	}
1252 
1253 	/* store the error if it has changed */
1254 	if (display) {
1255 		clear_last_error();
1256 		if (!error_filename) {
1257 			error_filename = "Unknown";
1258 		}
1259 		PG(last_error_type) = type;
1260 		PG(last_error_message) = zend_string_copy(message);
1261 		PG(last_error_file) = strdup(error_filename);
1262 		PG(last_error_lineno) = error_lineno;
1263 	}
1264 
1265 	/* display/log the error if necessary */
1266 	if (display && ((EG(error_reporting) & type) || (type & E_CORE))
1267 		&& (PG(log_errors) || PG(display_errors) || (!module_initialized))) {
1268 		char *error_type_str;
1269 		int syslog_type_int = LOG_NOTICE;
1270 
1271 		switch (type) {
1272 			case E_ERROR:
1273 			case E_CORE_ERROR:
1274 			case E_COMPILE_ERROR:
1275 			case E_USER_ERROR:
1276 				error_type_str = "Fatal error";
1277 				syslog_type_int = LOG_ERR;
1278 				break;
1279 			case E_RECOVERABLE_ERROR:
1280 				error_type_str = "Recoverable fatal error";
1281 				syslog_type_int = LOG_ERR;
1282 				break;
1283 			case E_WARNING:
1284 			case E_CORE_WARNING:
1285 			case E_COMPILE_WARNING:
1286 			case E_USER_WARNING:
1287 				error_type_str = "Warning";
1288 				syslog_type_int = LOG_WARNING;
1289 				break;
1290 			case E_PARSE:
1291 				error_type_str = "Parse error";
1292 				syslog_type_int = LOG_ERR;
1293 				break;
1294 			case E_NOTICE:
1295 			case E_USER_NOTICE:
1296 				error_type_str = "Notice";
1297 				syslog_type_int = LOG_NOTICE;
1298 				break;
1299 			case E_STRICT:
1300 				error_type_str = "Strict Standards";
1301 				syslog_type_int = LOG_INFO;
1302 				break;
1303 			case E_DEPRECATED:
1304 			case E_USER_DEPRECATED:
1305 				error_type_str = "Deprecated";
1306 				syslog_type_int = LOG_INFO;
1307 				break;
1308 			default:
1309 				error_type_str = "Unknown error";
1310 				break;
1311 		}
1312 
1313 		if (PG(log_errors)
1314 				|| (!module_initialized && (!PG(display_startup_errors) || !PG(display_errors)))) {
1315 			char *log_buffer;
1316 #ifdef PHP_WIN32
1317 			if (type == E_CORE_ERROR || type == E_CORE_WARNING) {
1318 				syslog(LOG_ALERT, "PHP %s: %s (%s)", error_type_str, ZSTR_VAL(message), GetCommandLine());
1319 			}
1320 #endif
1321 			spprintf(&log_buffer, 0, "PHP %s:  %s in %s on line %" PRIu32, error_type_str, ZSTR_VAL(message), error_filename, error_lineno);
1322 			php_log_err_with_severity(log_buffer, syslog_type_int);
1323 			efree(log_buffer);
1324 		}
1325 
1326 		if (PG(display_errors) && ((module_initialized && !PG(during_request_startup)) || (PG(display_startup_errors)))) {
1327 			if (PG(xmlrpc_errors)) {
1328 				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);
1329 			} else {
1330 				char *prepend_string = INI_STR("error_prepend_string");
1331 				char *append_string = INI_STR("error_append_string");
1332 
1333 				if (PG(html_errors)) {
1334 					if (type == E_ERROR || type == E_PARSE) {
1335 						zend_string *buf = escape_html(ZSTR_VAL(message), ZSTR_LEN(message));
1336 						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));
1337 						zend_string_free(buf);
1338 					} else {
1339 						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));
1340 					}
1341 				} else {
1342 					/* Write CLI/CGI errors to stderr if display_errors = "stderr" */
1343 					if ((!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "cgi") || !strcmp(sapi_module.name, "phpdbg")) &&
1344 						PG(display_errors) == PHP_DISPLAY_ERRORS_STDERR
1345 					) {
1346 						fprintf(stderr, "%s: %s in %s on line %" PRIu32 "\n", error_type_str, ZSTR_VAL(message), error_filename, error_lineno);
1347 #ifdef PHP_WIN32
1348 						fflush(stderr);
1349 #endif
1350 					} else {
1351 						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));
1352 					}
1353 				}
1354 			}
1355 		}
1356 	}
1357 
1358 	/* Bail out if we can't recover */
1359 	switch (type) {
1360 		case E_CORE_ERROR:
1361 			if(!module_initialized) {
1362 				/* bad error in module startup - no way we can live with this */
1363 				exit(-2);
1364 			}
1365 		/* no break - intentionally */
1366 		case E_ERROR:
1367 		case E_RECOVERABLE_ERROR:
1368 		case E_PARSE:
1369 		case E_COMPILE_ERROR:
1370 		case E_USER_ERROR:
1371 			EG(exit_status) = 255;
1372 			if (module_initialized) {
1373 				if (!PG(display_errors) &&
1374 				    !SG(headers_sent) &&
1375 					SG(sapi_headers).http_response_code == 200
1376 				) {
1377 					sapi_header_line ctr = {0};
1378 
1379 					ctr.line = "HTTP/1.0 500 Internal Server Error";
1380 					ctr.line_len = sizeof("HTTP/1.0 500 Internal Server Error") - 1;
1381 					sapi_header_op(SAPI_HEADER_REPLACE, &ctr);
1382 				}
1383 				/* the parser would return 1 (failure), we can bail out nicely */
1384 				if (!(orig_type & E_DONT_BAIL)) {
1385 					/* restore memory limit */
1386 					zend_set_memory_limit(PG(memory_limit));
1387 					zend_objects_store_mark_destructed(&EG(objects_store));
1388 					zend_bailout();
1389 					return;
1390 				}
1391 			}
1392 			break;
1393 	}
1394 }
1395 /* }}} */
1396 
1397 /* {{{ php_get_current_user */
php_get_current_user(void)1398 PHPAPI char *php_get_current_user(void)
1399 {
1400 	zend_stat_t *pstat;
1401 
1402 	if (SG(request_info).current_user) {
1403 		return SG(request_info).current_user;
1404 	}
1405 
1406 	/* FIXME: I need to have this somehow handled if
1407 	USE_SAPI is defined, because cgi will also be
1408 	interfaced in USE_SAPI */
1409 
1410 	pstat = sapi_get_stat();
1411 
1412 	if (!pstat) {
1413 		return "";
1414 	} else {
1415 #ifdef PHP_WIN32
1416 		char *name = php_win32_get_username();
1417 		int len;
1418 
1419 		if (!name) {
1420 			return "";
1421 		}
1422 		len = (int)strlen(name);
1423 		name[len] = '\0';
1424 		SG(request_info).current_user_length = len;
1425 		SG(request_info).current_user = estrndup(name, len);
1426 		free(name);
1427 		return SG(request_info).current_user;
1428 #else
1429 		struct passwd *pwd;
1430 #if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX)
1431 		struct passwd _pw;
1432 		struct passwd *retpwptr = NULL;
1433 		int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
1434 		char *pwbuf;
1435 
1436 		if (pwbuflen < 1) {
1437 			return "";
1438 		}
1439 		pwbuf = emalloc(pwbuflen);
1440 		if (getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr) != 0) {
1441 			efree(pwbuf);
1442 			return "";
1443 		}
1444 		if (retpwptr == NULL) {
1445 			efree(pwbuf);
1446 			return "";
1447 		}
1448 		pwd = &_pw;
1449 #else
1450 		if ((pwd=getpwuid(pstat->st_uid))==NULL) {
1451 			return "";
1452 		}
1453 #endif
1454 		SG(request_info).current_user_length = strlen(pwd->pw_name);
1455 		SG(request_info).current_user = estrndup(pwd->pw_name, SG(request_info).current_user_length);
1456 #if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX)
1457 		efree(pwbuf);
1458 #endif
1459 		return SG(request_info).current_user;
1460 #endif
1461 	}
1462 }
1463 /* }}} */
1464 
1465 /* {{{ Sets the maximum time a script can run */
PHP_FUNCTION(set_time_limit)1466 PHP_FUNCTION(set_time_limit)
1467 {
1468 	zend_long new_timeout;
1469 	char *new_timeout_str;
1470 	int new_timeout_strlen;
1471 	zend_string *key;
1472 
1473 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &new_timeout) == FAILURE) {
1474 		RETURN_THROWS();
1475 	}
1476 
1477 	new_timeout_strlen = (int)zend_spprintf(&new_timeout_str, 0, ZEND_LONG_FMT, new_timeout);
1478 
1479 	key = zend_string_init("max_execution_time", sizeof("max_execution_time")-1, 0);
1480 	if (zend_alter_ini_entry_chars_ex(key, new_timeout_str, new_timeout_strlen, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == SUCCESS) {
1481 		RETVAL_TRUE;
1482 	} else {
1483 		RETVAL_FALSE;
1484 	}
1485 	zend_string_release_ex(key, 0);
1486 	efree(new_timeout_str);
1487 }
1488 /* }}} */
1489 
1490 /* {{{ php_fopen_wrapper_for_zend */
php_fopen_wrapper_for_zend(const char * filename,zend_string ** opened_path)1491 static FILE *php_fopen_wrapper_for_zend(const char *filename, zend_string **opened_path)
1492 {
1493 	return php_stream_open_wrapper_as_file((char *)filename, "rb", USE_PATH|IGNORE_URL_WIN|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE, opened_path);
1494 }
1495 /* }}} */
1496 
php_zend_stream_closer(void * handle)1497 static void php_zend_stream_closer(void *handle) /* {{{ */
1498 {
1499 	php_stream_close((php_stream*)handle);
1500 }
1501 /* }}} */
1502 
php_zend_stream_fsizer(void * handle)1503 static size_t php_zend_stream_fsizer(void *handle) /* {{{ */
1504 {
1505 	php_stream *stream = handle;
1506 	php_stream_statbuf ssb;
1507 
1508 	/* File size reported by stat() may be inaccurate if stream filters are used.
1509 	 * TODO: Should stat() be generally disabled if filters are used? */
1510 	if (stream->readfilters.head) {
1511 		return 0;
1512 	}
1513 
1514 	if (php_stream_stat(stream, &ssb) == 0) {
1515 		return ssb.sb.st_size;
1516 	}
1517 	return 0;
1518 }
1519 /* }}} */
1520 
php_stream_open_for_zend(const char * filename,zend_file_handle * handle)1521 static zend_result php_stream_open_for_zend(const char *filename, zend_file_handle *handle) /* {{{ */
1522 {
1523 	return php_stream_open_for_zend_ex(filename, handle, USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE);
1524 }
1525 /* }}} */
1526 
php_stream_open_for_zend_ex(const char * filename,zend_file_handle * handle,int mode)1527 PHPAPI zend_result php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode) /* {{{ */
1528 {
1529 	zend_string *opened_path;
1530 	php_stream *stream = php_stream_open_wrapper((char *)filename, "rb", mode, &opened_path);
1531 	if (stream) {
1532 		memset(handle, 0, sizeof(zend_file_handle));
1533 		handle->type = ZEND_HANDLE_STREAM;
1534 		handle->filename = (char*)filename;
1535 		handle->opened_path = opened_path;
1536 		handle->handle.stream.handle  = stream;
1537 		handle->handle.stream.reader  = (zend_stream_reader_t)_php_stream_read;
1538 		handle->handle.stream.fsizer  = php_zend_stream_fsizer;
1539 		handle->handle.stream.isatty  = 0;
1540 		handle->handle.stream.closer = php_zend_stream_closer;
1541 		/* suppress warning if this stream is not explicitly closed */
1542 		php_stream_auto_cleanup(stream);
1543 		/* Disable buffering to avoid double buffering between PHP and Zend streams. */
1544 		php_stream_set_option(stream, PHP_STREAM_OPTION_READ_BUFFER, PHP_STREAM_BUFFER_NONE, NULL);
1545 
1546 		return SUCCESS;
1547 	}
1548 	return FAILURE;
1549 }
1550 /* }}} */
1551 
php_resolve_path_for_zend(const char * filename,size_t filename_len)1552 static zend_string *php_resolve_path_for_zend(const char *filename, size_t filename_len) /* {{{ */
1553 {
1554 	return php_resolve_path(filename, filename_len, PG(include_path));
1555 }
1556 /* }}} */
1557 
1558 /* {{{ php_get_configuration_directive_for_zend */
php_get_configuration_directive_for_zend(zend_string * name)1559 static zval *php_get_configuration_directive_for_zend(zend_string *name)
1560 {
1561 	return cfg_get_entry_ex(name);
1562 }
1563 /* }}} */
1564 
1565 /* {{{ php_free_request_globals */
php_free_request_globals(void)1566 static void php_free_request_globals(void)
1567 {
1568 	clear_last_error();
1569 	if (PG(php_sys_temp_dir)) {
1570 		efree(PG(php_sys_temp_dir));
1571 		PG(php_sys_temp_dir) = NULL;
1572 	}
1573 }
1574 /* }}} */
1575 
1576 /* {{{ php_message_handler_for_zend */
php_message_handler_for_zend(zend_long message,const void * data)1577 static ZEND_COLD void php_message_handler_for_zend(zend_long message, const void *data)
1578 {
1579 	switch (message) {
1580 		case ZMSG_FAILED_INCLUDE_FOPEN:
1581 			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)));
1582 			break;
1583 		case ZMSG_FAILED_REQUIRE_FOPEN:
1584 			zend_throw_error(NULL, "Failed opening required '%s' (include_path='%s')", php_strip_url_passwd((char *) data), STR_PRINT(PG(include_path)));
1585 			break;
1586 		case ZMSG_FAILED_HIGHLIGHT_FOPEN:
1587 			php_error_docref(NULL, E_WARNING, "Failed opening '%s' for highlighting", php_strip_url_passwd((char *) data));
1588 			break;
1589 		case ZMSG_MEMORY_LEAK_DETECTED:
1590 		case ZMSG_MEMORY_LEAK_REPEATED:
1591 #if ZEND_DEBUG
1592 			if (EG(error_reporting) & E_WARNING) {
1593 				char memory_leak_buf[1024];
1594 
1595 				if (message==ZMSG_MEMORY_LEAK_DETECTED) {
1596 					zend_leak_info *t = (zend_leak_info *) data;
1597 
1598 					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));
1599 					if (t->orig_filename) {
1600 						char relay_buf[512];
1601 
1602 						snprintf(relay_buf, 512, "%s(%" PRIu32 ") : Actual location (location was relayed)\n", t->orig_filename, t->orig_lineno);
1603 						strlcat(memory_leak_buf, relay_buf, sizeof(memory_leak_buf));
1604 					}
1605 				} else {
1606 					unsigned long leak_count = (zend_uintptr_t) data;
1607 
1608 					snprintf(memory_leak_buf, 512, "Last leak repeated %lu time%s\n", leak_count, (leak_count>1?"s":""));
1609 				}
1610 #	if defined(PHP_WIN32)
1611 				if (IsDebuggerPresent()) {
1612 					OutputDebugString(memory_leak_buf);
1613 				} else {
1614 					fprintf(stderr, "%s", memory_leak_buf);
1615 				}
1616 #	else
1617 				fprintf(stderr, "%s", memory_leak_buf);
1618 #	endif
1619 			}
1620 #endif
1621 			break;
1622 		case ZMSG_MEMORY_LEAKS_GRAND_TOTAL:
1623 #if ZEND_DEBUG
1624 			if (EG(error_reporting) & E_WARNING) {
1625 				char memory_leak_buf[512];
1626 
1627 				snprintf(memory_leak_buf, 512, "=== Total %d memory leaks detected ===\n", *((uint32_t *) data));
1628 #	if defined(PHP_WIN32)
1629 				if (IsDebuggerPresent()) {
1630 					OutputDebugString(memory_leak_buf);
1631 				} else {
1632 					fprintf(stderr, "%s", memory_leak_buf);
1633 				}
1634 #	else
1635 				fprintf(stderr, "%s", memory_leak_buf);
1636 #	endif
1637 			}
1638 #endif
1639 			break;
1640 		case ZMSG_LOG_SCRIPT_NAME: {
1641 				struct tm *ta, tmbuf;
1642 				time_t curtime;
1643 				char *datetime_str, asctimebuf[52];
1644 				char memory_leak_buf[4096];
1645 
1646 				time(&curtime);
1647 				ta = php_localtime_r(&curtime, &tmbuf);
1648 				datetime_str = php_asctime_r(ta, asctimebuf);
1649 				if (datetime_str) {
1650 					datetime_str[strlen(datetime_str)-1]=0;	/* get rid of the trailing newline */
1651 					snprintf(memory_leak_buf, sizeof(memory_leak_buf), "[%s]  Script:  '%s'\n", datetime_str, SAFE_FILENAME(SG(request_info).path_translated));
1652 				} else {
1653 					snprintf(memory_leak_buf, sizeof(memory_leak_buf), "[null]  Script:  '%s'\n", SAFE_FILENAME(SG(request_info).path_translated));
1654 				}
1655 #	if defined(PHP_WIN32)
1656 				if (IsDebuggerPresent()) {
1657 					OutputDebugString(memory_leak_buf);
1658 				} else {
1659 					fprintf(stderr, "%s", memory_leak_buf);
1660 				}
1661 #	else
1662 				fprintf(stderr, "%s", memory_leak_buf);
1663 #	endif
1664 			}
1665 			break;
1666 	}
1667 }
1668 /* }}} */
1669 
1670 
php_on_timeout(int seconds)1671 void php_on_timeout(int seconds)
1672 {
1673 	PG(connection_status) |= PHP_CONNECTION_TIMEOUT;
1674 }
1675 
1676 #if PHP_SIGCHILD
1677 /* {{{ sigchld_handler */
sigchld_handler(int apar)1678 static void sigchld_handler(int apar)
1679 {
1680 	int errno_save = errno;
1681 
1682 	while (waitpid(-1, NULL, WNOHANG) > 0);
1683 	signal(SIGCHLD, sigchld_handler);
1684 
1685 	errno = errno_save;
1686 }
1687 /* }}} */
1688 #endif
1689 
1690 /* {{{ php_request_startup */
php_request_startup(void)1691 int php_request_startup(void)
1692 {
1693 	int retval = SUCCESS;
1694 
1695 	zend_interned_strings_activate();
1696 
1697 #ifdef HAVE_DTRACE
1698 	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));
1699 #endif /* HAVE_DTRACE */
1700 
1701 #ifdef PHP_WIN32
1702 # if defined(ZTS)
1703 	_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
1704 # endif
1705 	PG(com_initialized) = 0;
1706 #endif
1707 
1708 #if PHP_SIGCHILD
1709 	signal(SIGCHLD, sigchld_handler);
1710 #endif
1711 
1712 	zend_try {
1713 		PG(in_error_log) = 0;
1714 		PG(during_request_startup) = 1;
1715 
1716 		php_output_activate();
1717 
1718 		/* initialize global variables */
1719 		PG(modules_activated) = 0;
1720 		PG(header_is_being_sent) = 0;
1721 		PG(connection_status) = PHP_CONNECTION_NORMAL;
1722 		PG(in_user_include) = 0;
1723 
1724 		zend_activate();
1725 		sapi_activate();
1726 
1727 #ifdef ZEND_SIGNALS
1728 		zend_signal_activate();
1729 #endif
1730 
1731 		if (PG(max_input_time) == -1) {
1732 			zend_set_timeout(EG(timeout_seconds), 1);
1733 		} else {
1734 			zend_set_timeout(PG(max_input_time), 1);
1735 		}
1736 
1737 		/* Disable realpath cache if an open_basedir is set */
1738 		if (PG(open_basedir) && *PG(open_basedir)) {
1739 			CWDG(realpath_cache_size_limit) = 0;
1740 		}
1741 
1742 		if (PG(expose_php)) {
1743 			sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
1744 		}
1745 
1746 		if (PG(output_handler) && PG(output_handler)[0]) {
1747 			zval oh;
1748 
1749 			ZVAL_STRING(&oh, PG(output_handler));
1750 			php_output_start_user(&oh, 0, PHP_OUTPUT_HANDLER_STDFLAGS);
1751 			zval_ptr_dtor(&oh);
1752 		} else if (PG(output_buffering)) {
1753 			php_output_start_user(NULL, PG(output_buffering) > 1 ? PG(output_buffering) : 0, PHP_OUTPUT_HANDLER_STDFLAGS);
1754 		} else if (PG(implicit_flush)) {
1755 			php_output_set_implicit_flush(1);
1756 		}
1757 
1758 		/* We turn this off in php_execute_script() */
1759 		/* PG(during_request_startup) = 0; */
1760 
1761 		php_hash_environment();
1762 		zend_activate_modules();
1763 		PG(modules_activated)=1;
1764 	} zend_catch {
1765 		retval = FAILURE;
1766 	} zend_end_try();
1767 
1768 	SG(sapi_started) = 1;
1769 
1770 	return retval;
1771 }
1772 /* }}} */
1773 
1774 /* {{{ php_request_shutdown */
php_request_shutdown(void * dummy)1775 void php_request_shutdown(void *dummy)
1776 {
1777 	zend_bool report_memleaks;
1778 
1779 	EG(flags) |= EG_FLAGS_IN_SHUTDOWN;
1780 
1781 	report_memleaks = PG(report_memleaks);
1782 
1783 	/* EG(current_execute_data) points into nirvana and therefore cannot be safely accessed
1784 	 * inside zend_executor callback functions.
1785 	 */
1786 	EG(current_execute_data) = NULL;
1787 
1788 	php_deactivate_ticks();
1789 
1790 	/* 0. Call any open observer end handlers that are still open after a zend_bailout */
1791 	if (ZEND_OBSERVER_ENABLED) {
1792 		zend_observer_fcall_end_all();
1793 	}
1794 
1795 	/* 1. Call all possible shutdown functions registered with register_shutdown_function() */
1796 	if (PG(modules_activated)) {
1797 		php_call_shutdown_functions();
1798 	}
1799 
1800 	/* 2. Call all possible __destruct() functions */
1801 	zend_try {
1802 		zend_call_destructors();
1803 	} zend_end_try();
1804 
1805 	/* 3. Flush all output buffers */
1806 	zend_try {
1807 		zend_bool send_buffer = SG(request_info).headers_only ? 0 : 1;
1808 
1809 		if (CG(unclean_shutdown) && PG(last_error_type) == E_ERROR &&
1810 			(size_t)PG(memory_limit) < zend_memory_usage(1)
1811 		) {
1812 			send_buffer = 0;
1813 		}
1814 
1815 		if (!send_buffer) {
1816 			php_output_discard_all();
1817 		} else {
1818 			php_output_end_all();
1819 		}
1820 	} zend_end_try();
1821 
1822 	/* 4. Reset max_execution_time (no longer executing php code after response sent) */
1823 	zend_try {
1824 		zend_unset_timeout();
1825 	} zend_end_try();
1826 
1827 	/* 5. Call all extensions RSHUTDOWN functions */
1828 	if (PG(modules_activated)) {
1829 		zend_deactivate_modules();
1830 	}
1831 
1832 	/* 6. Shutdown output layer (send the set HTTP headers, cleanup output handlers, etc.) */
1833 	zend_try {
1834 		php_output_deactivate();
1835 	} zend_end_try();
1836 
1837 	/* 7. Free shutdown functions */
1838 	if (PG(modules_activated)) {
1839 		php_free_shutdown_functions();
1840 	}
1841 
1842 	/* 8. Destroy super-globals */
1843 	zend_try {
1844 		int i;
1845 
1846 		for (i=0; i<NUM_TRACK_VARS; i++) {
1847 			zval_ptr_dtor(&PG(http_globals)[i]);
1848 		}
1849 	} zend_end_try();
1850 
1851 	/* 9. Shutdown scanner/executor/compiler and restore ini entries */
1852 	zend_deactivate();
1853 
1854 	/* 10. free request-bound globals */
1855 	php_free_request_globals();
1856 
1857 	/* 11. Call all extensions post-RSHUTDOWN functions */
1858 	zend_try {
1859 		zend_post_deactivate_modules();
1860 	} zend_end_try();
1861 
1862 	/* 12. SAPI related shutdown (free stuff) */
1863 	zend_try {
1864 		sapi_deactivate();
1865 	} zend_end_try();
1866 
1867 	/* 13. free virtual CWD memory */
1868 	virtual_cwd_deactivate();
1869 
1870 	/* 14. Destroy stream hashes */
1871 	zend_try {
1872 		php_shutdown_stream_hashes();
1873 	} zend_end_try();
1874 
1875 	/* 15. Free Willy (here be crashes) */
1876 	zend_interned_strings_deactivate();
1877 	zend_try {
1878 		shutdown_memory_manager(CG(unclean_shutdown) || !report_memleaks, 0);
1879 	} zend_end_try();
1880 
1881 	/* Reset memory limit, as the reset during INI_STAGE_DEACTIVATE may have failed.
1882 	 * At this point, no memory beyond a single chunk should be in use. */
1883 	zend_set_memory_limit(PG(memory_limit));
1884 
1885 	/* 16. Deactivate Zend signals */
1886 #ifdef ZEND_SIGNALS
1887 	zend_signal_deactivate();
1888 #endif
1889 
1890 #ifdef PHP_WIN32
1891 	if (PG(com_initialized)) {
1892 		CoUninitialize();
1893 		PG(com_initialized) = 0;
1894 	}
1895 #endif
1896 
1897 #ifdef HAVE_DTRACE
1898 	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));
1899 #endif /* HAVE_DTRACE */
1900 }
1901 /* }}} */
1902 
1903 /* {{{ php_com_initialize */
php_com_initialize(void)1904 PHPAPI void php_com_initialize(void)
1905 {
1906 #ifdef PHP_WIN32
1907 	if (!PG(com_initialized)) {
1908 		if (CoInitialize(NULL) == S_OK) {
1909 			PG(com_initialized) = 1;
1910 		}
1911 	}
1912 #endif
1913 }
1914 /* }}} */
1915 
1916 #ifdef ZTS
1917 /* {{{ core_globals_ctor */
core_globals_ctor(php_core_globals * core_globals)1918 static void core_globals_ctor(php_core_globals *core_globals)
1919 {
1920 	memset(core_globals, 0, sizeof(*core_globals));
1921 	php_startup_ticks();
1922 }
1923 /* }}} */
1924 #endif
1925 
1926 /* {{{ core_globals_dtor */
core_globals_dtor(php_core_globals * core_globals)1927 static void core_globals_dtor(php_core_globals *core_globals)
1928 {
1929 	/* These should have been freed earlier. */
1930 	ZEND_ASSERT(!core_globals->last_error_message);
1931 	ZEND_ASSERT(!core_globals->last_error_file);
1932 
1933 	if (core_globals->disable_classes) {
1934 		free(core_globals->disable_classes);
1935 	}
1936 	if (core_globals->php_binary) {
1937 		free(core_globals->php_binary);
1938 	}
1939 
1940 	php_shutdown_ticks();
1941 }
1942 /* }}} */
1943 
PHP_MINFO_FUNCTION(php_core)1944 PHP_MINFO_FUNCTION(php_core) { /* {{{ */
1945 	php_info_print_table_start();
1946 	php_info_print_table_row(2, "PHP Version", PHP_VERSION);
1947 	php_info_print_table_end();
1948 	DISPLAY_INI_ENTRIES();
1949 }
1950 /* }}} */
1951 
1952 /* {{{ php_register_extensions */
php_register_extensions(zend_module_entry * const * ptr,int count)1953 int php_register_extensions(zend_module_entry * const * ptr, int count)
1954 {
1955 	zend_module_entry * const * end = ptr + count;
1956 
1957 	while (ptr < end) {
1958 		if (*ptr) {
1959 			if (zend_register_internal_module(*ptr)==NULL) {
1960 				return FAILURE;
1961 			}
1962 		}
1963 		ptr++;
1964 	}
1965 	return SUCCESS;
1966 }
1967 
1968 /* A very long time ago php_module_startup() was refactored in a way
1969  * which broke calling it with more than one additional module.
1970  * This alternative to php_register_extensions() works around that
1971  * by walking the shallower structure.
1972  *
1973  * See algo: https://bugs.php.net/bug.php?id=63159
1974  */
php_register_extensions_bc(zend_module_entry * ptr,int count)1975 static int php_register_extensions_bc(zend_module_entry *ptr, int count)
1976 {
1977 	while (count--) {
1978 		if (zend_register_internal_module(ptr++) == NULL) {
1979 			return FAILURE;
1980  		}
1981 	}
1982 	return SUCCESS;
1983 }
1984 /* }}} */
1985 
1986 #ifdef PHP_WIN32
1987 static _invalid_parameter_handler old_invalid_parameter_handler;
1988 
dummy_invalid_parameter_handler(const wchar_t * expression,const wchar_t * function,const wchar_t * file,unsigned int line,uintptr_t pEwserved)1989 void dummy_invalid_parameter_handler(
1990 		const wchar_t *expression,
1991 		const wchar_t *function,
1992 		const wchar_t *file,
1993 		unsigned int   line,
1994 		uintptr_t      pEwserved)
1995 {
1996 	static int called = 0;
1997 	char buf[1024];
1998 	int len;
1999 
2000 	if (!called) {
2001 			if(PG(windows_show_crt_warning)) {
2002 			called = 1;
2003 			if (function) {
2004 				if (file) {
2005 					len = _snprintf(buf, sizeof(buf)-1, "Invalid parameter detected in CRT function '%ws' (%ws:%u)", function, file, line);
2006 				} else {
2007 					len = _snprintf(buf, sizeof(buf)-1, "Invalid parameter detected in CRT function '%ws'", function);
2008 				}
2009 			} else {
2010 				len = _snprintf(buf, sizeof(buf)-1, "Invalid CRT parameter detected (function not known)");
2011 			}
2012 			zend_error(E_WARNING, "%s", buf);
2013 			called = 0;
2014 		}
2015 	}
2016 }
2017 #endif
2018 
2019 /* {{{ php_module_startup */
php_module_startup(sapi_module_struct * sf,zend_module_entry * additional_modules,uint32_t num_additional_modules)2020 int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint32_t num_additional_modules)
2021 {
2022 	zend_utility_functions zuf;
2023 	zend_utility_values zuv;
2024 	int retval = SUCCESS, module_number=0;	/* for REGISTER_INI_ENTRIES() */
2025 	char *php_os;
2026 	zend_module_entry *module;
2027 
2028 #ifdef PHP_WIN32
2029 	WORD wVersionRequested = MAKEWORD(2, 0);
2030 	WSADATA wsaData;
2031 
2032 	php_os = "WINNT";
2033 
2034 	old_invalid_parameter_handler =
2035 		_set_invalid_parameter_handler(dummy_invalid_parameter_handler);
2036 	if (old_invalid_parameter_handler != NULL) {
2037 		_set_invalid_parameter_handler(old_invalid_parameter_handler);
2038 	}
2039 
2040 	/* Disable the message box for assertions.*/
2041 	_CrtSetReportMode(_CRT_ASSERT, 0);
2042 #else
2043 	php_os = PHP_OS;
2044 #endif
2045 
2046 #ifdef ZTS
2047 	(void)ts_resource(0);
2048 #endif
2049 
2050 #ifdef PHP_WIN32
2051 	if (!php_win32_init_random_bytes()) {
2052 		fprintf(stderr, "\ncrypt algorithm provider initialization failed\n");
2053 		return FAILURE;
2054 	}
2055 #endif
2056 
2057 	module_shutdown = 0;
2058 	module_startup = 1;
2059 	sapi_initialize_empty_request();
2060 	sapi_activate();
2061 
2062 	if (module_initialized) {
2063 		return SUCCESS;
2064 	}
2065 
2066 	sapi_module = *sf;
2067 
2068 	php_output_startup();
2069 
2070 #ifdef ZTS
2071 	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);
2072 #ifdef PHP_WIN32
2073 	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);
2074 #endif
2075 #else
2076 	memset(&core_globals, 0, sizeof(core_globals));
2077 	php_startup_ticks();
2078 #endif
2079 	gc_globals_ctor();
2080 
2081 	zuf.error_function = php_error_cb;
2082 	zuf.printf_function = php_printf;
2083 	zuf.write_function = php_output_write;
2084 	zuf.fopen_function = php_fopen_wrapper_for_zend;
2085 	zuf.message_handler = php_message_handler_for_zend;
2086 	zuf.get_configuration_directive = php_get_configuration_directive_for_zend;
2087 	zuf.ticks_function = php_run_ticks;
2088 	zuf.on_timeout = php_on_timeout;
2089 	zuf.stream_open_function = php_stream_open_for_zend;
2090 	zuf.printf_to_smart_string_function = php_printf_to_smart_string;
2091 	zuf.printf_to_smart_str_function = php_printf_to_smart_str;
2092 	zuf.getenv_function = sapi_getenv;
2093 	zuf.resolve_path_function = php_resolve_path_for_zend;
2094 	zend_startup(&zuf);
2095 	zend_update_current_locale();
2096 
2097 	zend_observer_startup();
2098 #if ZEND_DEBUG
2099 	zend_observer_error_register(report_zend_debug_error_notify_cb);
2100 #endif
2101 
2102 #if HAVE_TZSET
2103 	tzset();
2104 #endif
2105 
2106 #ifdef PHP_WIN32
2107 	char *img_err;
2108 	if (!php_win32_crt_compatible(&img_err)) {
2109 		php_error(E_CORE_WARNING, img_err);
2110 		efree(img_err);
2111 		return FAILURE;
2112 	}
2113 
2114 	/* start up winsock services */
2115 	if (WSAStartup(wVersionRequested, &wsaData) != 0) {
2116 		php_printf("\nwinsock.dll unusable. %d\n", WSAGetLastError());
2117 		return FAILURE;
2118 	}
2119 	php_win32_signal_ctrl_handler_init();
2120 #endif
2121 
2122 	le_index_ptr = zend_register_list_destructors_ex(NULL, NULL, "index pointer", 0);
2123 
2124 	/* Register constants */
2125 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_VERSION", PHP_VERSION, sizeof(PHP_VERSION)-1, CONST_PERSISTENT | CONST_CS);
2126 	REGISTER_MAIN_LONG_CONSTANT("PHP_MAJOR_VERSION", PHP_MAJOR_VERSION, CONST_PERSISTENT | CONST_CS);
2127 	REGISTER_MAIN_LONG_CONSTANT("PHP_MINOR_VERSION", PHP_MINOR_VERSION, CONST_PERSISTENT | CONST_CS);
2128 	REGISTER_MAIN_LONG_CONSTANT("PHP_RELEASE_VERSION", PHP_RELEASE_VERSION, CONST_PERSISTENT | CONST_CS);
2129 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_EXTRA_VERSION", PHP_EXTRA_VERSION, sizeof(PHP_EXTRA_VERSION) - 1, CONST_PERSISTENT | CONST_CS);
2130 	REGISTER_MAIN_LONG_CONSTANT("PHP_VERSION_ID", PHP_VERSION_ID, CONST_PERSISTENT | CONST_CS);
2131 #ifdef ZTS
2132 	REGISTER_MAIN_LONG_CONSTANT("PHP_ZTS", 1, CONST_PERSISTENT | CONST_CS);
2133 #else
2134 	REGISTER_MAIN_LONG_CONSTANT("PHP_ZTS", 0, CONST_PERSISTENT | CONST_CS);
2135 #endif
2136 	REGISTER_MAIN_LONG_CONSTANT("PHP_DEBUG", PHP_DEBUG, CONST_PERSISTENT | CONST_CS);
2137 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_OS", php_os, strlen(php_os), CONST_PERSISTENT | CONST_CS);
2138 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_OS_FAMILY", PHP_OS_FAMILY, sizeof(PHP_OS_FAMILY)-1, CONST_PERSISTENT | CONST_CS);
2139 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_SAPI", sapi_module.name, strlen(sapi_module.name), CONST_PERSISTENT | CONST_CS | CONST_NO_FILE_CACHE);
2140 	REGISTER_MAIN_STRINGL_CONSTANT("DEFAULT_INCLUDE_PATH", PHP_INCLUDE_PATH, sizeof(PHP_INCLUDE_PATH)-1, CONST_PERSISTENT | CONST_CS);
2141 	REGISTER_MAIN_STRINGL_CONSTANT("PEAR_INSTALL_DIR", PEAR_INSTALLDIR, sizeof(PEAR_INSTALLDIR)-1, CONST_PERSISTENT | CONST_CS);
2142 	REGISTER_MAIN_STRINGL_CONSTANT("PEAR_EXTENSION_DIR", PHP_EXTENSION_DIR, sizeof(PHP_EXTENSION_DIR)-1, CONST_PERSISTENT | CONST_CS);
2143 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_EXTENSION_DIR", PHP_EXTENSION_DIR, sizeof(PHP_EXTENSION_DIR)-1, CONST_PERSISTENT | CONST_CS);
2144 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_PREFIX", PHP_PREFIX, sizeof(PHP_PREFIX)-1, CONST_PERSISTENT | CONST_CS);
2145 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINDIR", PHP_BINDIR, sizeof(PHP_BINDIR)-1, CONST_PERSISTENT | CONST_CS);
2146 #ifndef PHP_WIN32
2147 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_MANDIR", PHP_MANDIR, sizeof(PHP_MANDIR)-1, CONST_PERSISTENT | CONST_CS);
2148 #endif
2149 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_LIBDIR", PHP_LIBDIR, sizeof(PHP_LIBDIR)-1, CONST_PERSISTENT | CONST_CS);
2150 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_DATADIR", PHP_DATADIR, sizeof(PHP_DATADIR)-1, CONST_PERSISTENT | CONST_CS);
2151 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_SYSCONFDIR", PHP_SYSCONFDIR, sizeof(PHP_SYSCONFDIR)-1, CONST_PERSISTENT | CONST_CS);
2152 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_LOCALSTATEDIR", PHP_LOCALSTATEDIR, sizeof(PHP_LOCALSTATEDIR)-1, CONST_PERSISTENT | CONST_CS);
2153 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS);
2154 	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);
2155 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
2156 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
2157 	REGISTER_MAIN_LONG_CONSTANT("PHP_MAXPATHLEN", MAXPATHLEN, CONST_PERSISTENT | CONST_CS);
2158 	REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", ZEND_LONG_MAX, CONST_PERSISTENT | CONST_CS);
2159 	REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MIN", ZEND_LONG_MIN, CONST_PERSISTENT | CONST_CS);
2160 	REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", SIZEOF_ZEND_LONG, CONST_PERSISTENT | CONST_CS);
2161 	REGISTER_MAIN_LONG_CONSTANT("PHP_FD_SETSIZE", FD_SETSIZE, CONST_PERSISTENT | CONST_CS);
2162 	REGISTER_MAIN_LONG_CONSTANT("PHP_FLOAT_DIG", DBL_DIG, CONST_PERSISTENT | CONST_CS);
2163 	REGISTER_MAIN_DOUBLE_CONSTANT("PHP_FLOAT_EPSILON", DBL_EPSILON, CONST_PERSISTENT | CONST_CS);
2164 	REGISTER_MAIN_DOUBLE_CONSTANT("PHP_FLOAT_MAX", DBL_MAX, CONST_PERSISTENT | CONST_CS);
2165 	REGISTER_MAIN_DOUBLE_CONSTANT("PHP_FLOAT_MIN", DBL_MIN, CONST_PERSISTENT | CONST_CS);
2166 
2167 #ifdef PHP_WIN32
2168 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_MAJOR",      EG(windows_version_info).dwMajorVersion, CONST_PERSISTENT | CONST_CS);
2169 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_MINOR",      EG(windows_version_info).dwMinorVersion, CONST_PERSISTENT | CONST_CS);
2170 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_BUILD",      EG(windows_version_info).dwBuildNumber, CONST_PERSISTENT | CONST_CS);
2171 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_PLATFORM",   EG(windows_version_info).dwPlatformId, CONST_PERSISTENT | CONST_CS);
2172 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_SP_MAJOR",   EG(windows_version_info).wServicePackMajor, CONST_PERSISTENT | CONST_CS);
2173 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_SP_MINOR",   EG(windows_version_info).wServicePackMinor, CONST_PERSISTENT | CONST_CS);
2174 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_SUITEMASK",  EG(windows_version_info).wSuiteMask, CONST_PERSISTENT | CONST_CS);
2175 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_PRODUCTTYPE", EG(windows_version_info).wProductType, CONST_PERSISTENT | CONST_CS);
2176 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_NT_DOMAIN_CONTROLLER", VER_NT_DOMAIN_CONTROLLER, CONST_PERSISTENT | CONST_CS);
2177 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_NT_SERVER", VER_NT_SERVER, CONST_PERSISTENT | CONST_CS);
2178 	REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_NT_WORKSTATION", VER_NT_WORKSTATION, CONST_PERSISTENT | CONST_CS);
2179 #endif
2180 
2181 	php_binary_init();
2182 	if (PG(php_binary)) {
2183 		REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY", PG(php_binary), strlen(PG(php_binary)), CONST_PERSISTENT | CONST_CS | CONST_NO_FILE_CACHE);
2184 	} else {
2185 		REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY", "", 0, CONST_PERSISTENT | CONST_CS | CONST_NO_FILE_CACHE);
2186 	}
2187 
2188 	php_output_register_constants();
2189 	php_rfc1867_register_constants();
2190 
2191 	/* this will read in php.ini, set up the configuration parameters,
2192 	   load zend extensions and register php function extensions
2193 	   to be loaded later */
2194 	if (php_init_config() == FAILURE) {
2195 		return FAILURE;
2196 	}
2197 
2198 	/* Register PHP core ini entries */
2199 	REGISTER_INI_ENTRIES();
2200 
2201 	/* Register Zend ini entries */
2202 	zend_register_standard_ini_entries();
2203 
2204 #ifdef ZEND_WIN32
2205 	/* Until the current ini values was setup, the current cp is 65001.
2206 		If the actual ini values are different, some stuff needs to be updated.
2207 		It concerns at least main_cwd_state and there might be more. As we're
2208 		still in the startup phase, lets use the chance and reinit the relevant
2209 		item according to the current codepage. Still, if ini_set() is used
2210 		later on, a more intelligent way to update such stuff is needed.
2211 		Startup/shutdown routines could involve touching globals and thus
2212 		can't always be used on demand. */
2213 	if (!php_win32_cp_use_unicode()) {
2214 		virtual_cwd_main_cwd_init(1);
2215 	}
2216 #endif
2217 
2218 	/* Disable realpath cache if an open_basedir is set */
2219 	if (PG(open_basedir) && *PG(open_basedir)) {
2220 		CWDG(realpath_cache_size_limit) = 0;
2221 	}
2222 
2223 	PG(have_called_openlog) = 0;
2224 
2225 	/* initialize stream wrappers registry
2226 	 * (this uses configuration parameters from php.ini)
2227 	 */
2228 	if (php_init_stream_wrappers(module_number) == FAILURE)	{
2229 		php_printf("PHP:  Unable to initialize stream url wrappers.\n");
2230 		return FAILURE;
2231 	}
2232 
2233 	zuv.html_errors = 1;
2234 	php_startup_auto_globals();
2235 	zend_set_utility_values(&zuv);
2236 	php_startup_sapi_content_types();
2237 
2238 	/* Begin to fingerprint the process state */
2239 	zend_startup_system_id();
2240 
2241 	/* startup extensions statically compiled in */
2242 	if (php_register_internal_extensions_func() == FAILURE) {
2243 		php_printf("Unable to start builtin modules\n");
2244 		return FAILURE;
2245 	}
2246 
2247 	/* start additional PHP extensions */
2248 	php_register_extensions_bc(additional_modules, num_additional_modules);
2249 
2250 	/* load and startup extensions compiled as shared objects (aka DLLs)
2251 	   as requested by php.ini entries
2252 	   these are loaded after initialization of internal extensions
2253 	   as extensions *might* rely on things from ext/standard
2254 	   which is always an internal extension and to be initialized
2255 	   ahead of all other internals
2256 	 */
2257 	php_ini_register_extensions();
2258 	zend_startup_modules();
2259 
2260 	/* start Zend extensions */
2261 	zend_startup_extensions();
2262 
2263 	zend_collect_module_handlers();
2264 
2265 	/* register additional functions */
2266 	if (sapi_module.additional_functions) {
2267 		if ((module = zend_hash_str_find_ptr(&module_registry, "standard", sizeof("standard")-1)) != NULL) {
2268 			EG(current_module) = module;
2269 			zend_register_functions(NULL, sapi_module.additional_functions, NULL, MODULE_PERSISTENT);
2270 			EG(current_module) = NULL;
2271 		}
2272 	}
2273 
2274 	/* disable certain classes and functions as requested by php.ini */
2275 	zend_disable_functions(INI_STR("disable_functions"));
2276 	php_disable_classes();
2277 
2278 	/* make core report what it should */
2279 	if ((module = zend_hash_str_find_ptr(&module_registry, "core", sizeof("core")-1)) != NULL) {
2280 		module->version = PHP_VERSION;
2281 		module->info_func = PHP_MINFO(php_core);
2282 	}
2283 
2284 	/* Extensions that add engine hooks after this point do so at their own peril */
2285 	zend_finalize_system_id();
2286 
2287 	module_initialized = 1;
2288 
2289 	if (zend_post_startup() != SUCCESS) {
2290 		return FAILURE;
2291 	}
2292 
2293 	/* Check for deprecated directives */
2294 	/* NOTE: If you add anything here, remember to add it to build/Makefile.global! */
2295 	{
2296 		struct {
2297 			const long error_level;
2298 			const char *phrase;
2299 			const char *directives[18]; /* Remember to change this if the number of directives change */
2300 		} directives[2] = {
2301 			{
2302 				E_DEPRECATED,
2303 				"Directive '%s' is deprecated",
2304 				{
2305 					"allow_url_include",
2306 					NULL
2307 				}
2308 			},
2309 			{
2310 				E_CORE_ERROR,
2311 				"Directive '%s' is no longer available in PHP",
2312 				{
2313 					"allow_call_time_pass_reference",
2314 					"asp_tags",
2315 					"define_syslog_variables",
2316 					"highlight.bg",
2317 					"magic_quotes_gpc",
2318 					"magic_quotes_runtime",
2319 					"magic_quotes_sybase",
2320 					"register_globals",
2321 					"register_long_arrays",
2322 					"safe_mode",
2323 					"safe_mode_gid",
2324 					"safe_mode_include_dir",
2325 					"safe_mode_exec_dir",
2326 					"safe_mode_allowed_env_vars",
2327 					"safe_mode_protected_env_vars",
2328 					"zend.ze1_compatibility_mode",
2329 					"track_errors",
2330 					NULL
2331 				}
2332 			}
2333 		};
2334 
2335 		unsigned int i;
2336 
2337 		zend_try {
2338 			/* 2 = Count of deprecation structs */
2339 			for (i = 0; i < 2; i++) {
2340 				const char **p = directives[i].directives;
2341 
2342 				while(*p) {
2343 					zend_long value;
2344 
2345 					if (cfg_get_long((char*)*p, &value) == SUCCESS && value) {
2346 						zend_error(directives[i].error_level, directives[i].phrase, *p);
2347 					}
2348 
2349 					++p;
2350 				}
2351 			}
2352 		} zend_catch {
2353 			retval = FAILURE;
2354 		} zend_end_try();
2355 	}
2356 
2357 	virtual_cwd_deactivate();
2358 
2359 	sapi_deactivate();
2360 	module_startup = 0;
2361 
2362 	/* Don't leak errors from startup into the per-request phase. */
2363 	clear_last_error();
2364 	shutdown_memory_manager(1, 0);
2365  	virtual_cwd_activate();
2366 
2367 	zend_interned_strings_switch_storage(1);
2368 
2369 #if ZEND_RC_DEBUG
2370 	zend_rc_debug = 1;
2371 #endif
2372 
2373 	/* we're done */
2374 	return retval;
2375 }
2376 /* }}} */
2377 
2378 /* {{{ php_module_shutdown_wrapper */
php_module_shutdown_wrapper(sapi_module_struct * sapi_globals)2379 int php_module_shutdown_wrapper(sapi_module_struct *sapi_globals)
2380 {
2381 	php_module_shutdown();
2382 	return SUCCESS;
2383 }
2384 /* }}} */
2385 
2386 /* {{{ php_module_shutdown */
php_module_shutdown(void)2387 void php_module_shutdown(void)
2388 {
2389 	int module_number=0;	/* for UNREGISTER_INI_ENTRIES() */
2390 
2391 	module_shutdown = 1;
2392 
2393 	if (!module_initialized) {
2394 		return;
2395 	}
2396 
2397 	zend_interned_strings_switch_storage(0);
2398 
2399 #if ZEND_RC_DEBUG
2400 	zend_rc_debug = 0;
2401 #endif
2402 
2403 #ifdef PHP_WIN32
2404 	(void)php_win32_shutdown_random_bytes();
2405 	php_win32_signal_ctrl_handler_shutdown();
2406 #endif
2407 
2408 	sapi_flush();
2409 
2410 	zend_shutdown();
2411 
2412 #ifdef PHP_WIN32
2413 	/*close winsock */
2414 	WSACleanup();
2415 #endif
2416 
2417 	/* Destroys filter & transport registries too */
2418 	php_shutdown_stream_wrappers(module_number);
2419 
2420 	UNREGISTER_INI_ENTRIES();
2421 
2422 	/* close down the ini config */
2423 	php_shutdown_config();
2424 	clear_last_error();
2425 
2426 #ifndef ZTS
2427 	zend_ini_shutdown();
2428 	shutdown_memory_manager(CG(unclean_shutdown), 1);
2429 #else
2430 	zend_ini_global_shutdown();
2431 #endif
2432 
2433 	php_output_shutdown();
2434 
2435 #ifndef ZTS
2436 	zend_interned_strings_dtor();
2437 #endif
2438 
2439 	if (zend_post_shutdown_cb) {
2440 		void (*cb)(void) = zend_post_shutdown_cb;
2441 
2442 		zend_post_shutdown_cb = NULL;
2443 		cb();
2444 	}
2445 
2446 	module_initialized = 0;
2447 
2448 #ifndef ZTS
2449 	core_globals_dtor(&core_globals);
2450 	gc_globals_dtor();
2451 #else
2452 	ts_free_id(core_globals_id);
2453 #endif
2454 
2455 #ifdef PHP_WIN32
2456 	if (old_invalid_parameter_handler == NULL) {
2457 		_set_invalid_parameter_handler(old_invalid_parameter_handler);
2458 	}
2459 #endif
2460 
2461 	zend_observer_shutdown();
2462 }
2463 /* }}} */
2464 
2465 /* {{{ php_execute_script */
php_execute_script(zend_file_handle * primary_file)2466 PHPAPI int php_execute_script(zend_file_handle *primary_file)
2467 {
2468 	zend_file_handle *prepend_file_p, *append_file_p;
2469 	zend_file_handle prepend_file, append_file;
2470 #ifdef HAVE_BROKEN_GETCWD
2471 	volatile int old_cwd_fd = -1;
2472 #else
2473 	char *old_cwd;
2474 	ALLOCA_FLAG(use_heap)
2475 #endif
2476 	int retval = 0;
2477 
2478 #ifndef HAVE_BROKEN_GETCWD
2479 # define OLD_CWD_SIZE 4096
2480 	old_cwd = do_alloca(OLD_CWD_SIZE, use_heap);
2481 	old_cwd[0] = '\0';
2482 #endif
2483 
2484 	zend_try {
2485 		char realfile[MAXPATHLEN];
2486 
2487 #ifdef PHP_WIN32
2488 		if(primary_file->filename) {
2489 			UpdateIniFromRegistry((char*)primary_file->filename);
2490 		}
2491 #endif
2492 
2493 		PG(during_request_startup) = 0;
2494 
2495 		if (primary_file->filename && !(SG(options) & SAPI_OPTION_NO_CHDIR)) {
2496 #ifdef HAVE_BROKEN_GETCWD
2497 			/* this looks nasty to me */
2498 			old_cwd_fd = open(".", 0);
2499 #else
2500 			php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1));
2501 #endif
2502 			VCWD_CHDIR_FILE(primary_file->filename);
2503 		}
2504 
2505  		/* Only lookup the real file path and add it to the included_files list if already opened
2506 		 *   otherwise it will get opened and added to the included_files list in zend_execute_scripts
2507 		 */
2508  		if (primary_file->filename &&
2509  		    strcmp("Standard input code", primary_file->filename) &&
2510  			primary_file->opened_path == NULL &&
2511  			primary_file->type != ZEND_HANDLE_FILENAME
2512 		) {
2513 			if (expand_filepath(primary_file->filename, realfile)) {
2514 				primary_file->opened_path = zend_string_init(realfile, strlen(realfile), 0);
2515 				zend_hash_add_empty_element(&EG(included_files), primary_file->opened_path);
2516 			}
2517 		}
2518 
2519 		if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) {
2520 			zend_stream_init_filename(&prepend_file, PG(auto_prepend_file));
2521 			prepend_file_p = &prepend_file;
2522 		} else {
2523 			prepend_file_p = NULL;
2524 		}
2525 
2526 		if (PG(auto_append_file) && PG(auto_append_file)[0]) {
2527 			zend_stream_init_filename(&append_file, PG(auto_append_file));
2528 			append_file_p = &append_file;
2529 		} else {
2530 			append_file_p = NULL;
2531 		}
2532 		if (PG(max_input_time) != -1) {
2533 #ifdef PHP_WIN32
2534 			zend_unset_timeout();
2535 #endif
2536 			zend_set_timeout(INI_INT("max_execution_time"), 0);
2537 		}
2538 
2539 		retval = (zend_execute_scripts(ZEND_REQUIRE, NULL, 3, prepend_file_p, primary_file, append_file_p) == SUCCESS);
2540 	} zend_end_try();
2541 
2542 	if (EG(exception)) {
2543 		zend_try {
2544 			zend_exception_error(EG(exception), E_ERROR);
2545 		} zend_end_try();
2546 	}
2547 
2548 #ifdef HAVE_BROKEN_GETCWD
2549 	if (old_cwd_fd != -1) {
2550 		fchdir(old_cwd_fd);
2551 		close(old_cwd_fd);
2552 	}
2553 #else
2554 	if (old_cwd[0] != '\0') {
2555 		php_ignore_value(VCWD_CHDIR(old_cwd));
2556 	}
2557 	free_alloca(old_cwd, use_heap);
2558 #endif
2559 	return retval;
2560 }
2561 /* }}} */
2562 
2563 /* {{{ php_execute_simple_script */
php_execute_simple_script(zend_file_handle * primary_file,zval * ret)2564 PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval *ret)
2565 {
2566 	char *old_cwd;
2567 	ALLOCA_FLAG(use_heap)
2568 
2569 	EG(exit_status) = 0;
2570 #define OLD_CWD_SIZE 4096
2571 	old_cwd = do_alloca(OLD_CWD_SIZE, use_heap);
2572 	old_cwd[0] = '\0';
2573 
2574 	zend_try {
2575 #ifdef PHP_WIN32
2576 		if(primary_file->filename) {
2577 			UpdateIniFromRegistry((char*)primary_file->filename);
2578 		}
2579 #endif
2580 
2581 		PG(during_request_startup) = 0;
2582 
2583 		if (primary_file->filename && !(SG(options) & SAPI_OPTION_NO_CHDIR)) {
2584 			php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1));
2585 			VCWD_CHDIR_FILE(primary_file->filename);
2586 		}
2587 		zend_execute_scripts(ZEND_REQUIRE, ret, 1, primary_file);
2588 	} zend_end_try();
2589 
2590 	if (old_cwd[0] != '\0') {
2591 		php_ignore_value(VCWD_CHDIR(old_cwd));
2592 	}
2593 
2594 	free_alloca(old_cwd, use_heap);
2595 	return EG(exit_status);
2596 }
2597 /* }}} */
2598 
2599 /* {{{ php_handle_aborted_connection */
php_handle_aborted_connection(void)2600 PHPAPI void php_handle_aborted_connection(void)
2601 {
2602 
2603 	PG(connection_status) = PHP_CONNECTION_ABORTED;
2604 	php_output_set_status(PHP_OUTPUT_DISABLED);
2605 
2606 	if (!PG(ignore_user_abort)) {
2607 		zend_bailout();
2608 	}
2609 }
2610 /* }}} */
2611 
2612 /* {{{ php_handle_auth_data */
php_handle_auth_data(const char * auth)2613 PHPAPI int php_handle_auth_data(const char *auth)
2614 {
2615 	int ret = -1;
2616 	size_t auth_len = auth != NULL ? strlen(auth) : 0;
2617 
2618 	if (auth && auth_len > 0 && zend_binary_strncasecmp(auth, auth_len, "Basic ", sizeof("Basic ")-1, sizeof("Basic ")-1) == 0) {
2619 		char *pass;
2620 		zend_string *user;
2621 
2622 		user = php_base64_decode((const unsigned char*)auth + 6, auth_len - 6);
2623 		if (user) {
2624 			pass = strchr(ZSTR_VAL(user), ':');
2625 			if (pass) {
2626 				*pass++ = '\0';
2627 				SG(request_info).auth_user = estrndup(ZSTR_VAL(user), ZSTR_LEN(user));
2628 				SG(request_info).auth_password = estrdup(pass);
2629 				ret = 0;
2630 			}
2631 			zend_string_free(user);
2632 		}
2633 	}
2634 
2635 	if (ret == -1) {
2636 		SG(request_info).auth_user = SG(request_info).auth_password = NULL;
2637 	} else {
2638 		SG(request_info).auth_digest = NULL;
2639 	}
2640 
2641 	if (ret == -1 && auth && auth_len > 0 && zend_binary_strncasecmp(auth, auth_len, "Digest ", sizeof("Digest ")-1, sizeof("Digest ")-1) == 0) {
2642 		SG(request_info).auth_digest = estrdup(auth + 7);
2643 		ret = 0;
2644 	}
2645 
2646 	if (ret == -1) {
2647 		SG(request_info).auth_digest = NULL;
2648 	}
2649 
2650 	return ret;
2651 }
2652 /* }}} */
2653 
2654 /* {{{ php_lint_script */
php_lint_script(zend_file_handle * file)2655 PHPAPI int php_lint_script(zend_file_handle *file)
2656 {
2657 	zend_op_array *op_array;
2658 	int retval = FAILURE;
2659 
2660 	zend_try {
2661 		op_array = zend_compile_file(file, ZEND_INCLUDE);
2662 		zend_destroy_file_handle(file);
2663 
2664 		if (op_array) {
2665 			destroy_op_array(op_array);
2666 			efree(op_array);
2667 			retval = SUCCESS;
2668 		}
2669 	} zend_end_try();
2670 	if (EG(exception)) {
2671 		zend_exception_error(EG(exception), E_ERROR);
2672 	}
2673 
2674 	return retval;
2675 }
2676 /* }}} */
2677 
2678 #ifdef ZTS
2679 /* {{{ php_reserve_tsrm_memory */
php_reserve_tsrm_memory(void)2680 PHPAPI void php_reserve_tsrm_memory(void)
2681 {
2682 	tsrm_reserve(
2683 		TSRM_ALIGNED_SIZE(sizeof(zend_compiler_globals)) +
2684 		TSRM_ALIGNED_SIZE(sizeof(zend_executor_globals)) +
2685 		TSRM_ALIGNED_SIZE(sizeof(zend_php_scanner_globals)) +
2686 		TSRM_ALIGNED_SIZE(sizeof(zend_ini_scanner_globals)) +
2687 		TSRM_ALIGNED_SIZE(sizeof(virtual_cwd_globals)) +
2688 #ifdef ZEND_SIGNALS
2689 		TSRM_ALIGNED_SIZE(sizeof(zend_signal_globals_t)) +
2690 #endif
2691 		TSRM_ALIGNED_SIZE(zend_mm_globals_size()) +
2692 		TSRM_ALIGNED_SIZE(zend_gc_globals_size()) +
2693 		TSRM_ALIGNED_SIZE(sizeof(php_core_globals)) +
2694 		TSRM_ALIGNED_SIZE(sizeof(sapi_globals_struct))
2695 	);
2696 }
2697 /* }}} */
2698 
2699 /* {{{ php_tsrm_startup */
php_tsrm_startup(void)2700 PHPAPI int php_tsrm_startup(void)
2701 {
2702 	int ret = tsrm_startup(1, 1, 0, NULL);
2703 	php_reserve_tsrm_memory();
2704 	(void)ts_resource(0);
2705 	return ret;
2706 }
2707 /* }}} */
2708 #endif
2709