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