Coverage Report

Created: 2026-02-14 06:52

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