Coverage Report

Created: 2026-10-28 06:20

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