Coverage Report

Created: 2025-09-27 06:26

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