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