Coverage Report

Created: 2026-07-25 06:39

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