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