Coverage Report

Created: 2025-12-14 06:05

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