Coverage Report

Created: 2025-04-03 08:40

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