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