Coverage Report

Created: 2026-09-14 06:25

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