Coverage Report

Created: 2025-06-13 06:43

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