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