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