Coverage Report

Created: 2026-06-02 06:36

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