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