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