Coverage Report

Created: 2022-10-06 21:30

/src/php-src/Zend/zend.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
   +----------------------------------------------------------------------+
3
   | Zend Engine                                                          |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 2.00 of the Zend license,     |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available through the world-wide-web at the following url:           |
10
   | http://www.zend.com/license/2_00.txt.                                |
11
   | If you did not receive a copy of the Zend license and are unable to  |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@zend.com so we can mail you a copy immediately.              |
14
   +----------------------------------------------------------------------+
15
   | Authors: Andi Gutmans <andi@php.net>                                 |
16
   |          Zeev Suraski <zeev@php.net>                                 |
17
   +----------------------------------------------------------------------+
18
*/
19
20
#include "zend.h"
21
#include "zend_extensions.h"
22
#include "zend_modules.h"
23
#include "zend_constants.h"
24
#include "zend_list.h"
25
#include "zend_API.h"
26
#include "zend_exceptions.h"
27
#include "zend_builtin_functions.h"
28
#include "zend_ini.h"
29
#include "zend_vm.h"
30
#include "zend_dtrace.h"
31
#include "zend_virtual_cwd.h"
32
#include "zend_smart_str.h"
33
#include "zend_smart_string.h"
34
#include "zend_cpuinfo.h"
35
#include "zend_attributes.h"
36
37
static size_t global_map_ptr_last = 0;
38
39
#ifdef ZTS
40
ZEND_API int compiler_globals_id;
41
ZEND_API int executor_globals_id;
42
ZEND_API size_t compiler_globals_offset;
43
ZEND_API size_t executor_globals_offset;
44
static HashTable *global_function_table = NULL;
45
static HashTable *global_class_table = NULL;
46
static HashTable *global_constants_table = NULL;
47
static HashTable *global_auto_globals_table = NULL;
48
static HashTable *global_persistent_list = NULL;
49
ZEND_TSRMLS_CACHE_DEFINE()
50
# define GLOBAL_FUNCTION_TABLE    global_function_table
51
# define GLOBAL_CLASS_TABLE     global_class_table
52
# define GLOBAL_CONSTANTS_TABLE   global_constants_table
53
# define GLOBAL_AUTO_GLOBALS_TABLE  global_auto_globals_table
54
#else
55
6.83k
# define GLOBAL_FUNCTION_TABLE    CG(function_table)
56
6.83k
# define GLOBAL_CLASS_TABLE     CG(class_table)
57
6.83k
# define GLOBAL_AUTO_GLOBALS_TABLE  CG(auto_globals)
58
6.83k
# define GLOBAL_CONSTANTS_TABLE   EG(zend_constants)
59
#endif
60
61
ZEND_API zend_utility_values zend_uv;
62
ZEND_API zend_bool zend_dtrace_enabled;
63
64
zend_llist zend_error_notify_callbacks;
65
66
/* version information */
67
static char *zend_version_info;
68
static uint32_t zend_version_info_length;
69
6.83k
#define ZEND_CORE_VERSION_INFO  "Zend Engine v" ZEND_VERSION ", Copyright (c) Zend Technologies\n"
70
39.6k
#define PRINT_ZVAL_INDENT 4
71
72
/* true multithread-shared globals */
73
ZEND_API zend_class_entry *zend_standard_class_def = NULL;
74
ZEND_API size_t (*zend_printf)(const char *format, ...);
75
ZEND_API zend_write_func_t zend_write;
76
ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path);
77
ZEND_API zend_result (*zend_stream_open_function)(const char *filename, zend_file_handle *handle);
78
ZEND_API void (*zend_ticks_function)(int ticks);
79
ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data);
80
ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
81
void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap);
82
void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap);
83
ZEND_API char *(*zend_getenv)(const char *name, size_t name_len);
84
ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len);
85
ZEND_API zend_result (*zend_post_startup_cb)(void) = NULL;
86
ZEND_API void (*zend_post_shutdown_cb)(void) = NULL;
87
ZEND_API zend_result (*zend_preload_autoload)(zend_string *filename) = NULL;
88
89
/* This callback must be signal handler safe! */
90
void (*zend_on_timeout)(int seconds);
91
92
static void (*zend_message_dispatcher_p)(zend_long message, const void *data);
93
static zval *(*zend_get_configuration_directive_p)(zend_string *name);
94
95
#if ZEND_RC_DEBUG
96
ZEND_API zend_bool zend_rc_debug = 0;
97
#endif
98
99
static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
100
9.36k
{
101
9.36k
  if (!new_value) {
102
0
    EG(error_reporting) = E_ALL;
103
9.36k
  } else {
104
9.36k
    EG(error_reporting) = atoi(ZSTR_VAL(new_value));
105
9.36k
  }
106
9.36k
  return SUCCESS;
107
9.36k
}
108
/* }}} */
109
110
static ZEND_INI_MH(OnUpdateGCEnabled) /* {{{ */
111
7.26k
{
112
7.26k
  zend_bool val;
113
114
7.26k
  val = zend_ini_parse_bool(new_value);
115
7.26k
  gc_enable(val);
116
117
7.26k
  return SUCCESS;
118
7.26k
}
119
/* }}} */
120
121
static ZEND_INI_DISP(zend_gc_enabled_displayer_cb) /* {{{ */
122
40
{
123
40
  if (gc_enabled()) {
124
40
    ZEND_PUTS("On");
125
0
  } else {
126
0
    ZEND_PUTS("Off");
127
0
  }
128
40
}
129
/* }}} */
130
131
132
static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */
133
6.83k
{
134
6.83k
  if (!CG(multibyte)) {
135
6.83k
    return FAILURE;
136
6.83k
  }
137
0
  if (!zend_multibyte_get_functions()) {
138
0
    return SUCCESS;
139
0
  }
140
0
  return zend_multibyte_set_script_encoding_by_string(new_value ? ZSTR_VAL(new_value) : NULL, new_value ? ZSTR_LEN(new_value) : 0);
141
0
}
142
/* }}} */
143
144
static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */
145
7.49k
{
146
7.49k
  zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
147
148
7.49k
  zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
149
150
7.49k
  if (stage != ZEND_INI_STAGE_STARTUP &&
151
659
      stage != ZEND_INI_STAGE_SHUTDOWN &&
152
659
      *p != val &&
153
542
      (*p < 0 || val < 0)) {
154
29
    zend_error(E_WARNING, "zend.assertions may be completely enabled or disabled only in php.ini");
155
29
    return FAILURE;
156
29
  }
157
158
7.46k
  *p = val;
159
7.46k
  return SUCCESS;
160
7.46k
}
161
/* }}} */
162
163
static ZEND_INI_MH(OnSetExceptionStringParamMaxLen) /* {{{ */
164
8.85k
{
165
8.85k
  zend_long i;
166
167
8.85k
  ZEND_ATOL(i, ZSTR_VAL(new_value));
168
8.85k
  if (i >= 0 && i <= 1000000) {
169
8.20k
    EG(exception_string_param_max_len) = i;
170
8.20k
    return SUCCESS;
171
644
  } else {
172
644
    return FAILURE;
173
644
  }
174
8.85k
}
175
/* }}} */
176
177
#if ZEND_DEBUG
178
# define SIGNAL_CHECK_DEFAULT "1"
179
#else
180
# define SIGNAL_CHECK_DEFAULT "0"
181
#endif
182
183
ZEND_INI_BEGIN()
184
  ZEND_INI_ENTRY("error_reporting",       NULL,   ZEND_INI_ALL,   OnUpdateErrorReporting)
185
  STD_ZEND_INI_ENTRY("zend.assertions",       "1",    ZEND_INI_ALL,       OnUpdateAssertions,           assertions,   zend_executor_globals,  executor_globals)
186
  ZEND_INI_ENTRY3_EX("zend.enable_gc",        "1",  ZEND_INI_ALL,   OnUpdateGCEnabled, NULL, NULL, NULL, zend_gc_enabled_displayer_cb)
187
  STD_ZEND_INI_BOOLEAN("zend.multibyte", "0", ZEND_INI_PERDIR, OnUpdateBool, multibyte,      zend_compiler_globals, compiler_globals)
188
  ZEND_INI_ENTRY("zend.script_encoding",      NULL,   ZEND_INI_ALL,   OnUpdateScriptEncoding)
189
  STD_ZEND_INI_BOOLEAN("zend.detect_unicode",     "1",  ZEND_INI_ALL,   OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
190
#ifdef ZEND_SIGNALS
191
  STD_ZEND_INI_BOOLEAN("zend.signal_check", SIGNAL_CHECK_DEFAULT, ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals)
192
#endif
193
  STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args",  "0",  ZEND_INI_ALL,   OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals)
194
  STD_ZEND_INI_ENTRY("zend.exception_string_param_max_len", "15", ZEND_INI_ALL, OnSetExceptionStringParamMaxLen,  exception_string_param_max_len,   zend_executor_globals,  executor_globals)
195
ZEND_INI_END()
196
197
ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
198
3.33M
{
199
3.33M
  smart_string buf = {0};
200
201
  /* since there are places where (v)spprintf called without checking for null,
202
     a bit of defensive coding here */
203
3.33M
  if (!pbuf) {
204
0
    return 0;
205
0
  }
206
207
3.33M
  zend_printf_to_smart_string(&buf, format, ap);
208
209
3.33M
  if (max_len && buf.len > max_len) {
210
0
    buf.len = max_len;
211
0
  }
212
213
3.33M
  smart_string_0(&buf);
214
215
3.33M
  if (buf.c) {
216
3.33M
    *pbuf = buf.c;
217
3.33M
    return buf.len;
218
0
  } else {
219
0
    *pbuf = estrndup("", 0);
220
0
    return 0;
221
0
  }
222
3.33M
}
223
/* }}} */
224
225
ZEND_API size_t zend_spprintf(char **message, size_t max_len, const char *format, ...) /* {{{ */
226
842k
{
227
842k
  va_list arg;
228
842k
  size_t len;
229
230
842k
  va_start(arg, format);
231
842k
  len = zend_vspprintf(message, max_len, format, arg);
232
842k
  va_end(arg);
233
842k
  return len;
234
842k
}
235
/* }}} */
236
237
ZEND_API size_t zend_spprintf_unchecked(char **message, size_t max_len, const char *format, ...) /* {{{ */
238
0
{
239
0
  va_list arg;
240
0
  size_t len;
241
242
0
  va_start(arg, format);
243
0
  len = zend_vspprintf(message, max_len, format, arg);
244
0
  va_end(arg);
245
0
  return len;
246
0
}
247
/* }}} */
248
249
ZEND_API zend_string *zend_vstrpprintf(size_t max_len, const char *format, va_list ap) /* {{{ */
250
2.46M
{
251
2.46M
  smart_str buf = {0};
252
253
2.46M
  zend_printf_to_smart_str(&buf, format, ap);
254
255
2.46M
  if (!buf.s) {
256
0
    return ZSTR_EMPTY_ALLOC();
257
0
  }
258
259
2.46M
  if (max_len && ZSTR_LEN(buf.s) > max_len) {
260
0
    ZSTR_LEN(buf.s) = max_len;
261
0
  }
262
263
2.46M
  smart_str_0(&buf);
264
2.46M
  return buf.s;
265
2.46M
}
266
/* }}} */
267
268
ZEND_API zend_string *zend_strpprintf(size_t max_len, const char *format, ...) /* {{{ */
269
550k
{
270
550k
  va_list arg;
271
550k
  zend_string *str;
272
273
550k
  va_start(arg, format);
274
550k
  str = zend_vstrpprintf(max_len, format, arg);
275
550k
  va_end(arg);
276
550k
  return str;
277
550k
}
278
/* }}} */
279
280
ZEND_API zend_string *zend_strpprintf_unchecked(size_t max_len, const char *format, ...) /* {{{ */
281
21.0k
{
282
21.0k
  va_list arg;
283
21.0k
  zend_string *str;
284
285
21.0k
  va_start(arg, format);
286
21.0k
  str = zend_vstrpprintf(max_len, format, arg);
287
21.0k
  va_end(arg);
288
21.0k
  return str;
289
21.0k
}
290
/* }}} */
291
292
static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent);
293
294
static void print_hash(smart_str *buf, HashTable *ht, int indent, zend_bool is_object) /* {{{ */
295
11.0k
{
296
11.0k
  zval *tmp;
297
11.0k
  zend_string *string_key;
298
11.0k
  zend_ulong num_key;
299
11.0k
  int i;
300
301
44.0k
  for (i = 0; i < indent; i++) {
302
33.0k
    smart_str_appendc(buf, ' ');
303
33.0k
  }
304
11.0k
  smart_str_appends(buf, "(\n");
305
11.0k
  indent += PRINT_ZVAL_INDENT;
306
48.2k
  ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
307
162k
    for (i = 0; i < indent; i++) {
308
144k
      smart_str_appendc(buf, ' ');
309
144k
    }
310
17.5k
    smart_str_appendc(buf, '[');
311
17.5k
    if (string_key) {
312
8.34k
      if (is_object) {
313
1.66k
        const char *prop_name, *class_name;
314
1.66k
        size_t prop_len;
315
1.66k
        int mangled = zend_unmangle_property_name_ex(string_key, &class_name, &prop_name, &prop_len);
316
317
1.66k
        smart_str_appendl(buf, prop_name, prop_len);
318
1.66k
        if (class_name && mangled == SUCCESS) {
319
7
          if (class_name[0] == '*') {
320
4
            smart_str_appends(buf, ":protected");
321
3
          } else {
322
3
            smart_str_appends(buf, ":");
323
3
            smart_str_appends(buf, class_name);
324
3
            smart_str_appends(buf, ":private");
325
3
          }
326
7
        }
327
6.68k
      } else {
328
6.68k
        smart_str_append(buf, string_key);
329
6.68k
      }
330
9.20k
    } else {
331
9.20k
      smart_str_append_long(buf, num_key);
332
9.20k
    }
333
17.5k
    smart_str_appends(buf, "] => ");
334
17.5k
    zend_print_zval_r_to_buf(buf, tmp, indent+PRINT_ZVAL_INDENT);
335
17.5k
    smart_str_appends(buf, "\n");
336
17.5k
  } ZEND_HASH_FOREACH_END();
337
11.0k
  indent -= PRINT_ZVAL_INDENT;
338
44.0k
  for (i = 0; i < indent; i++) {
339
33.0k
    smart_str_appendc(buf, ' ');
340
33.0k
  }
341
11.0k
  smart_str_appends(buf, ")\n");
342
11.0k
}
343
/* }}} */
344
345
static void print_flat_hash(HashTable *ht) /* {{{ */
346
121
{
347
121
  zval *tmp;
348
121
  zend_string *string_key;
349
121
  zend_ulong num_key;
350
121
  int i = 0;
351
352
269
  ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
353
74
    if (i++ > 0) {
354
22
      ZEND_PUTS(",");
355
22
    }
356
74
    ZEND_PUTS("[");
357
74
    if (string_key) {
358
0
      ZEND_WRITE(ZSTR_VAL(string_key), ZSTR_LEN(string_key));
359
74
    } else {
360
74
      zend_printf(ZEND_ULONG_FMT, num_key);
361
74
    }
362
74
    ZEND_PUTS("] => ");
363
269
    zend_print_flat_zval_r(tmp);
364
74
  } ZEND_HASH_FOREACH_END();
365
121
}
366
/* }}} */
367
368
ZEND_API bool zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */
369
0
{
370
0
  if (Z_TYPE_P(expr) == IS_STRING) {
371
0
    return 0;
372
0
  } else {
373
0
    ZVAL_STR(expr_copy, zval_get_string_func(expr));
374
0
    return 1;
375
0
  }
376
0
}
377
/* }}} */
378
379
ZEND_API size_t zend_print_zval(zval *expr, int indent) /* {{{ */
380
2.87k
{
381
2.87k
  zend_string *tmp_str;
382
2.87k
  zend_string *str = zval_get_tmp_string(expr, &tmp_str);
383
2.87k
  size_t len = ZSTR_LEN(str);
384
385
2.87k
  if (len != 0) {
386
2.85k
    zend_write(ZSTR_VAL(str), len);
387
2.85k
  }
388
389
2.87k
  zend_tmp_string_release(tmp_str);
390
2.87k
  return len;
391
2.87k
}
392
/* }}} */
393
394
ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
395
2.59k
{
396
2.59k
  switch (Z_TYPE_P(expr)) {
397
52
    case IS_ARRAY:
398
52
      ZEND_PUTS("Array (");
399
52
      if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
400
52
        if (GC_IS_RECURSIVE(Z_ARRVAL_P(expr))) {
401
0
          ZEND_PUTS(" *RECURSION*");
402
0
          return;
403
0
        }
404
52
        GC_PROTECT_RECURSION(Z_ARRVAL_P(expr));
405
52
      }
406
52
      print_flat_hash(Z_ARRVAL_P(expr));
407
52
      ZEND_PUTS(")");
408
52
      if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
409
52
        GC_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
410
52
      }
411
52
      break;
412
69
    case IS_OBJECT:
413
69
    {
414
69
      HashTable *properties;
415
69
      zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr));
416
69
      zend_printf("%s Object (", ZSTR_VAL(class_name));
417
69
      zend_string_release_ex(class_name, 0);
418
419
69
      if (GC_IS_RECURSIVE(Z_COUNTED_P(expr))) {
420
0
        ZEND_PUTS(" *RECURSION*");
421
0
        return;
422
0
      }
423
424
69
      properties = Z_OBJPROP_P(expr);
425
69
      if (properties) {
426
69
        GC_PROTECT_RECURSION(Z_OBJ_P(expr));
427
69
        print_flat_hash(properties);
428
69
        GC_UNPROTECT_RECURSION(Z_OBJ_P(expr));
429
69
      }
430
69
      ZEND_PUTS(")");
431
69
      break;
432
69
    }
433
50
    case IS_REFERENCE:
434
50
      zend_print_flat_zval_r(Z_REFVAL_P(expr));
435
50
      break;
436
2.42k
    default:
437
2.42k
      zend_print_zval(expr, 0);
438
2.42k
      break;
439
2.59k
  }
440
2.59k
}
441
/* }}} */
442
443
static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* {{{ */
444
26.4k
{
445
26.4k
  switch (Z_TYPE_P(expr)) {
446
9.39k
    case IS_ARRAY:
447
9.39k
      smart_str_appends(buf, "Array\n");
448
9.39k
      if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
449
8.71k
        if (GC_IS_RECURSIVE(Z_ARRVAL_P(expr))) {
450
10
          smart_str_appends(buf, " *RECURSION*");
451
10
          return;
452
10
        }
453
8.70k
        GC_PROTECT_RECURSION(Z_ARRVAL_P(expr));
454
8.70k
      }
455
9.38k
      print_hash(buf, Z_ARRVAL_P(expr), indent, 0);
456
9.38k
      if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
457
8.70k
        GC_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
458
8.70k
      }
459
9.38k
      break;
460
1.65k
    case IS_OBJECT:
461
1.65k
      {
462
1.65k
        HashTable *properties;
463
464
1.65k
        zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr));
465
1.65k
        smart_str_appends(buf, ZSTR_VAL(class_name));
466
1.65k
        zend_string_release_ex(class_name, 0);
467
468
1.65k
        smart_str_appends(buf, " Object\n");
469
1.65k
        if (GC_IS_RECURSIVE(Z_OBJ_P(expr))) {
470
0
          smart_str_appends(buf, " *RECURSION*");
471
0
          return;
472
0
        }
473
474
1.65k
        if ((properties = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_DEBUG)) == NULL) {
475
0
          break;
476
0
        }
477
478
1.65k
        GC_PROTECT_RECURSION(Z_OBJ_P(expr));
479
1.65k
        print_hash(buf, properties, indent, 1);
480
1.65k
        GC_UNPROTECT_RECURSION(Z_OBJ_P(expr));
481
482
1.65k
        zend_release_properties(properties);
483
1.65k
        break;
484
1.65k
      }
485
4.91k
    case IS_LONG:
486
4.91k
      smart_str_append_long(buf, Z_LVAL_P(expr));
487
4.91k
      break;
488
176
    case IS_REFERENCE:
489
176
      zend_print_zval_r_to_buf(buf, Z_REFVAL_P(expr), indent);
490
176
      break;
491
9.64k
    case IS_STRING:
492
9.64k
      smart_str_append(buf, Z_STR_P(expr));
493
9.64k
      break;
494
709
    default:
495
709
      {
496
709
        zend_string *str = zval_get_string_func(expr);
497
709
        smart_str_append(buf, str);
498
709
        zend_string_release_ex(str, 0);
499
709
      }
500
709
      break;
501
26.4k
  }
502
26.4k
}
503
/* }}} */
504
505
ZEND_API zend_string *zend_print_zval_r_to_str(zval *expr, int indent) /* {{{ */
506
8.77k
{
507
8.77k
  smart_str buf = {0};
508
8.77k
  zend_print_zval_r_to_buf(&buf, expr, indent);
509
8.77k
  smart_str_0(&buf);
510
8.77k
  return buf.s;
511
8.77k
}
512
/* }}} */
513
514
ZEND_API void zend_print_zval_r(zval *expr, int indent) /* {{{ */
515
8.37k
{
516
8.37k
  zend_string *str = zend_print_zval_r_to_str(expr, indent);
517
8.37k
  zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
518
8.37k
  zend_string_release_ex(str, 0);
519
8.37k
}
520
/* }}} */
521
522
static FILE *zend_fopen_wrapper(const char *filename, zend_string **opened_path) /* {{{ */
523
0
{
524
0
  if (opened_path) {
525
0
    *opened_path = zend_string_init(filename, strlen(filename), 0);
526
0
  }
527
0
  return fopen(filename, "rb");
528
0
}
529
/* }}} */
530
531
#ifdef ZTS
532
static zend_bool short_tags_default      = 1;
533
static uint32_t compiler_options_default = ZEND_COMPILE_DEFAULT;
534
#else
535
6.83k
# define short_tags_default     1
536
6.83k
# define compiler_options_default ZEND_COMPILE_DEFAULT
537
#endif
538
539
static void zend_set_default_compile_time_values(void) /* {{{ */
540
6.83k
{
541
  /* default compile-time values */
542
6.83k
  CG(short_tags) = short_tags_default;
543
6.83k
  CG(compiler_options) = compiler_options_default;
544
545
6.83k
  CG(rtd_key_counter) = 0;
546
6.83k
}
547
/* }}} */
548
549
#ifdef ZEND_WIN32
550
static void zend_get_windows_version_info(OSVERSIONINFOEX *osvi) /* {{{ */
551
{
552
  ZeroMemory(osvi, sizeof(OSVERSIONINFOEX));
553
  osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
554
  if(!GetVersionEx((OSVERSIONINFO *) osvi)) {
555
    ZEND_UNREACHABLE(); /* Should not happen as sizeof is used. */
556
  }
557
}
558
/* }}} */
559
#endif
560
561
static void zend_init_exception_op(void) /* {{{ */
562
6.83k
{
563
6.83k
  memset(EG(exception_op), 0, sizeof(EG(exception_op)));
564
6.83k
  EG(exception_op)[0].opcode = ZEND_HANDLE_EXCEPTION;
565
6.83k
  ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op));
566
6.83k
  EG(exception_op)[1].opcode = ZEND_HANDLE_EXCEPTION;
567
6.83k
  ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1);
568
6.83k
  EG(exception_op)[2].opcode = ZEND_HANDLE_EXCEPTION;
569
6.83k
  ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+2);
570
6.83k
}
571
/* }}} */
572
573
static void zend_init_call_trampoline_op(void) /* {{{ */
574
6.83k
{
575
6.83k
  memset(&EG(call_trampoline_op), 0, sizeof(EG(call_trampoline_op)));
576
6.83k
  EG(call_trampoline_op).opcode = ZEND_CALL_TRAMPOLINE;
577
6.83k
  ZEND_VM_SET_OPCODE_HANDLER(&EG(call_trampoline_op));
578
6.83k
}
579
/* }}} */
580
581
static void auto_global_dtor(zval *zv) /* {{{ */
582
0
{
583
0
  free(Z_PTR_P(zv));
584
0
}
585
/* }}} */
586
587
#ifdef ZTS
588
static void function_copy_ctor(zval *zv) /* {{{ */
589
{
590
  zend_function *old_func = Z_FUNC_P(zv);
591
  zend_function *func;
592
593
  if (old_func->type == ZEND_USER_FUNCTION) {
594
    ZEND_ASSERT(old_func->op_array.fn_flags & ZEND_ACC_IMMUTABLE);
595
    return;
596
  }
597
  func = pemalloc(sizeof(zend_internal_function), 1);
598
  Z_FUNC_P(zv) = func;
599
  memcpy(func, old_func, sizeof(zend_internal_function));
600
  function_add_ref(func);
601
  if ((old_func->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS))
602
   && old_func->common.arg_info) {
603
    uint32_t i;
604
    uint32_t num_args = old_func->common.num_args + 1;
605
    zend_arg_info *arg_info = old_func->common.arg_info - 1;
606
    zend_arg_info *new_arg_info;
607
608
    if (old_func->common.fn_flags & ZEND_ACC_VARIADIC) {
609
      num_args++;
610
    }
611
    new_arg_info = pemalloc(sizeof(zend_arg_info) * num_args, 1);
612
    memcpy(new_arg_info, arg_info, sizeof(zend_arg_info) * num_args);
613
    for (i = 0 ; i < num_args; i++) {
614
      if (ZEND_TYPE_HAS_LIST(arg_info[i].type)) {
615
        zend_type_list *old_list = ZEND_TYPE_LIST(arg_info[i].type);
616
        zend_type_list *new_list = pemalloc(ZEND_TYPE_LIST_SIZE(old_list->num_types), 1);
617
        memcpy(new_list, old_list, ZEND_TYPE_LIST_SIZE(old_list->num_types));
618
        ZEND_TYPE_SET_PTR(new_arg_info[i].type, new_list);
619
620
        zend_type *list_type;
621
        ZEND_TYPE_LIST_FOREACH(new_list, list_type) {
622
          zend_string *name = zend_string_dup(ZEND_TYPE_NAME(*list_type), 1);
623
          ZEND_TYPE_SET_PTR(*list_type, name);
624
        } ZEND_TYPE_LIST_FOREACH_END();
625
      } else if (ZEND_TYPE_HAS_NAME(arg_info[i].type)) {
626
        zend_string *name = zend_string_dup(ZEND_TYPE_NAME(arg_info[i].type), 1);
627
        ZEND_TYPE_SET_PTR(new_arg_info[i].type, name);
628
      }
629
    }
630
    func->common.arg_info = new_arg_info + 1;
631
  }
632
}
633
/* }}} */
634
635
static void auto_global_copy_ctor(zval *zv) /* {{{ */
636
{
637
  zend_auto_global *old_ag = (zend_auto_global *) Z_PTR_P(zv);
638
  zend_auto_global *new_ag = pemalloc(sizeof(zend_auto_global), 1);
639
640
  new_ag->name = old_ag->name;
641
  new_ag->auto_global_callback = old_ag->auto_global_callback;
642
  new_ag->jit = old_ag->jit;
643
644
  Z_PTR_P(zv) = new_ag;
645
}
646
/* }}} */
647
648
static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{{ */
649
{
650
  compiler_globals->compiled_filename = NULL;
651
652
  compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
653
  zend_hash_init(compiler_globals->function_table, 1024, NULL, ZEND_FUNCTION_DTOR, 1);
654
  zend_hash_copy(compiler_globals->function_table, global_function_table, function_copy_ctor);
655
656
  compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
657
  zend_hash_init(compiler_globals->class_table, 64, NULL, ZEND_CLASS_DTOR, 1);
658
  zend_hash_copy(compiler_globals->class_table, global_class_table, zend_class_add_ref);
659
660
  zend_set_default_compile_time_values();
661
662
  compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable));
663
  zend_hash_init(compiler_globals->auto_globals, 8, NULL, auto_global_dtor, 1);
664
  zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, auto_global_copy_ctor);
665
666
  compiler_globals->script_encoding_list = NULL;
667
668
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
669
  /* Map region is going to be created and resized at run-time. */
670
  ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL);
671
  compiler_globals->map_ptr_size = 0;
672
  compiler_globals->map_ptr_last = global_map_ptr_last;
673
  if (compiler_globals->map_ptr_last) {
674
    /* Allocate map_ptr table */
675
    void *base;
676
    compiler_globals->map_ptr_size = ZEND_MM_ALIGNED_SIZE_EX(compiler_globals->map_ptr_last, 4096);
677
    base = pemalloc(compiler_globals->map_ptr_size * sizeof(void*), 1);
678
    ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, base);
679
    memset(base, 0, compiler_globals->map_ptr_last * sizeof(void*));
680
  }
681
#else
682
# error "Unknown ZEND_MAP_PTR_KIND"
683
#endif
684
}
685
/* }}} */
686
687
static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{{ */
688
{
689
  if (compiler_globals->function_table != GLOBAL_FUNCTION_TABLE) {
690
    zend_hash_destroy(compiler_globals->function_table);
691
    free(compiler_globals->function_table);
692
  }
693
  if (compiler_globals->class_table != GLOBAL_CLASS_TABLE) {
694
    zend_hash_destroy(compiler_globals->class_table);
695
    free(compiler_globals->class_table);
696
  }
697
  if (compiler_globals->auto_globals != GLOBAL_AUTO_GLOBALS_TABLE) {
698
    zend_hash_destroy(compiler_globals->auto_globals);
699
    free(compiler_globals->auto_globals);
700
  }
701
  if (compiler_globals->script_encoding_list) {
702
    pefree((char*)compiler_globals->script_encoding_list, 1);
703
  }
704
  if (ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base)) {
705
    free(ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base));
706
    ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL);
707
    compiler_globals->map_ptr_size = 0;
708
  }
709
}
710
/* }}} */
711
712
static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{{ */
713
{
714
  zend_startup_constants();
715
  zend_copy_constants(executor_globals->zend_constants, GLOBAL_CONSTANTS_TABLE);
716
  zend_init_rsrc_plist();
717
  zend_init_exception_op();
718
  zend_init_call_trampoline_op();
719
  memset(&executor_globals->trampoline, 0, sizeof(zend_op_array));
720
  executor_globals->lambda_count = 0;
721
  ZVAL_UNDEF(&executor_globals->user_error_handler);
722
  ZVAL_UNDEF(&executor_globals->user_exception_handler);
723
  executor_globals->in_autoload = NULL;
724
  executor_globals->current_execute_data = NULL;
725
  executor_globals->current_module = NULL;
726
  executor_globals->exit_status = 0;
727
#if XPFPA_HAVE_CW
728
  executor_globals->saved_fpu_cw = 0;
729
#endif
730
  executor_globals->saved_fpu_cw_ptr = NULL;
731
  executor_globals->active = 0;
732
  executor_globals->bailout = NULL;
733
  executor_globals->error_handling  = EH_NORMAL;
734
  executor_globals->exception_class = NULL;
735
  executor_globals->exception = NULL;
736
  executor_globals->objects_store.object_buckets = NULL;
737
#ifdef ZEND_WIN32
738
  zend_get_windows_version_info(&executor_globals->windows_version_info);
739
#endif
740
  executor_globals->flags = EG_FLAGS_INITIAL;
741
}
742
/* }}} */
743
744
static void executor_globals_dtor(zend_executor_globals *executor_globals) /* {{{ */
745
{
746
  zend_ini_dtor(executor_globals->ini_directives);
747
748
  if (&executor_globals->persistent_list != global_persistent_list) {
749
    zend_destroy_rsrc_list(&executor_globals->persistent_list);
750
  }
751
  if (executor_globals->zend_constants != GLOBAL_CONSTANTS_TABLE) {
752
    zend_hash_destroy(executor_globals->zend_constants);
753
    free(executor_globals->zend_constants);
754
  }
755
}
756
/* }}} */
757
758
static void zend_new_thread_end_handler(THREAD_T thread_id) /* {{{ */
759
{
760
  zend_copy_ini_directives();
761
  zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP);
762
}
763
/* }}} */
764
#endif
765
766
#if defined(__FreeBSD__) || defined(__DragonFly__)
767
/* FreeBSD and DragonFly floating point precision fix */
768
#include <floatingpoint.h>
769
#endif
770
771
static void ini_scanner_globals_ctor(zend_ini_scanner_globals *scanner_globals_p) /* {{{ */
772
6.83k
{
773
6.83k
  memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
774
6.83k
}
775
/* }}} */
776
777
static void php_scanner_globals_ctor(zend_php_scanner_globals *scanner_globals_p) /* {{{ */
778
6.83k
{
779
6.83k
  memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
780
6.83k
}
781
/* }}} */
782
783
static void module_destructor_zval(zval *zv) /* {{{ */
784
0
{
785
0
  zend_module_entry *module = (zend_module_entry*)Z_PTR_P(zv);
786
787
0
  module_destructor(module);
788
0
  free(module);
789
0
}
790
/* }}} */
791
792
static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
793
3.22k
{
794
3.22k
  zval globals;
795
796
  /* IS_ARRAY, but with ref-counter 1 and not IS_TYPE_REFCOUNTED */
797
3.22k
  ZVAL_ARR(&globals, &EG(symbol_table));
798
3.22k
  Z_TYPE_FLAGS_P(&globals) = 0;
799
3.22k
  ZVAL_NEW_REF(&globals, &globals);
800
3.22k
  zend_hash_update(&EG(symbol_table), name, &globals);
801
3.22k
  return 0;
802
3.22k
}
803
/* }}} */
804
805
void zend_startup(zend_utility_functions *utility_functions) /* {{{ */
806
6.83k
{
807
#ifdef ZTS
808
  zend_compiler_globals *compiler_globals;
809
  zend_executor_globals *executor_globals;
810
  extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
811
  extern ZEND_API ts_rsrc_id language_scanner_globals_id;
812
#else
813
6.83k
  extern zend_ini_scanner_globals ini_scanner_globals;
814
6.83k
  extern zend_php_scanner_globals language_scanner_globals;
815
6.83k
#endif
816
817
6.83k
  zend_cpu_startup();
818
819
#ifdef ZEND_WIN32
820
  php_win32_cp_set_by_id(65001);
821
#endif
822
823
6.83k
  start_memory_manager();
824
825
6.83k
  virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */
826
827
#if defined(__FreeBSD__) || defined(__DragonFly__)
828
  /* FreeBSD and DragonFly floating point precision fix */
829
  fpsetmask(0);
830
#endif
831
832
6.83k
  zend_startup_strtod();
833
6.83k
  zend_startup_extensions_mechanism();
834
6.83k
  zend_startup_error_notify_callbacks();
835
836
  /* Set up utility functions and values */
837
6.83k
  zend_error_cb = utility_functions->error_function;
838
6.83k
  zend_printf = utility_functions->printf_function;
839
6.83k
  zend_write = utility_functions->write_function;
840
6.83k
  zend_fopen = utility_functions->fopen_function;
841
6.83k
  if (!zend_fopen) {
842
0
    zend_fopen = zend_fopen_wrapper;
843
0
  }
844
6.83k
  zend_stream_open_function = utility_functions->stream_open_function;
845
6.83k
  zend_message_dispatcher_p = utility_functions->message_handler;
846
6.83k
  zend_get_configuration_directive_p = utility_functions->get_configuration_directive;
847
6.83k
  zend_ticks_function = utility_functions->ticks_function;
848
6.83k
  zend_on_timeout = utility_functions->on_timeout;
849
6.83k
  zend_printf_to_smart_string = utility_functions->printf_to_smart_string_function;
850
6.83k
  zend_printf_to_smart_str = utility_functions->printf_to_smart_str_function;
851
6.83k
  zend_getenv = utility_functions->getenv_function;
852
6.83k
  zend_resolve_path = utility_functions->resolve_path_function;
853
854
6.83k
  zend_interrupt_function = NULL;
855
856
#ifdef HAVE_DTRACE
857
/* build with dtrace support */
858
  {
859
    char *tmp = getenv("USE_ZEND_DTRACE");
860
861
    if (tmp && zend_atoi(tmp, 0)) {
862
      zend_dtrace_enabled = 1;
863
      zend_compile_file = dtrace_compile_file;
864
      zend_execute_ex = dtrace_execute_ex;
865
      zend_execute_internal = dtrace_execute_internal;
866
867
      zend_register_error_notify_callback(dtrace_error_notify_cb);
868
    } else {
869
      zend_compile_file = compile_file;
870
      zend_execute_ex = execute_ex;
871
      zend_execute_internal = NULL;
872
    }
873
  }
874
#else
875
6.83k
  zend_compile_file = compile_file;
876
6.83k
  zend_execute_ex = execute_ex;
877
6.83k
  zend_execute_internal = NULL;
878
6.83k
#endif /* HAVE_DTRACE */
879
6.83k
  zend_compile_string = compile_string;
880
6.83k
  zend_throw_exception_hook = NULL;
881
882
  /* Set up the default garbage collection implementation. */
883
6.83k
  gc_collect_cycles = zend_gc_collect_cycles;
884
885
6.83k
  zend_vm_init();
886
887
  /* set up version */
888
6.83k
  zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
889
6.83k
  zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO) - 1;
890
891
6.83k
  GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
892
6.83k
  GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
893
6.83k
  GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
894
6.83k
  GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable));
895
896
6.83k
  zend_hash_init(GLOBAL_FUNCTION_TABLE, 1024, NULL, ZEND_FUNCTION_DTOR, 1);
897
6.83k
  zend_hash_init(GLOBAL_CLASS_TABLE, 64, NULL, ZEND_CLASS_DTOR, 1);
898
6.83k
  zend_hash_init(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, auto_global_dtor, 1);
899
6.83k
  zend_hash_init(GLOBAL_CONSTANTS_TABLE, 128, NULL, ZEND_CONSTANT_DTOR, 1);
900
901
6.83k
  zend_hash_init(&module_registry, 32, NULL, module_destructor_zval, 1);
902
6.83k
  zend_init_rsrc_list_dtors();
903
904
#ifdef ZTS
905
  ts_allocate_fast_id(&compiler_globals_id, &compiler_globals_offset, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
906
  ts_allocate_fast_id(&executor_globals_id, &executor_globals_offset, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
907
  ts_allocate_fast_id(&language_scanner_globals_id, &language_scanner_globals_offset, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL);
908
  ts_allocate_fast_id(&ini_scanner_globals_id, &ini_scanner_globals_offset, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL);
909
  compiler_globals = ts_resource(compiler_globals_id);
910
  executor_globals = ts_resource(executor_globals_id);
911
912
  compiler_globals_dtor(compiler_globals);
913
  compiler_globals->in_compilation = 0;
914
  compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
915
  compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
916
917
  *compiler_globals->function_table = *GLOBAL_FUNCTION_TABLE;
918
  *compiler_globals->class_table = *GLOBAL_CLASS_TABLE;
919
  compiler_globals->auto_globals = GLOBAL_AUTO_GLOBALS_TABLE;
920
921
  zend_hash_destroy(executor_globals->zend_constants);
922
  *executor_globals->zend_constants = *GLOBAL_CONSTANTS_TABLE;
923
#else
924
6.83k
  ini_scanner_globals_ctor(&ini_scanner_globals);
925
6.83k
  php_scanner_globals_ctor(&language_scanner_globals);
926
6.83k
  zend_set_default_compile_time_values();
927
#ifdef ZEND_WIN32
928
  zend_get_windows_version_info(&EG(windows_version_info));
929
#endif
930
# if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
931
    /* Create a map region, used for indirect pointers from shared to
932
     * process memory. It's allocatred once and never resized.
933
     * All processes must map it into the same address space.
934
     */
935
    CG(map_ptr_size) = 1024 * 1024; // TODO: initial size ???
936
    CG(map_ptr_last) = 0;
937
    ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), pemalloc(CG(map_ptr_size) * sizeof(void*), 1));
938
# elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
939
    /* Map region is going to be created and resized at run-time. */
940
6.83k
    ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), NULL);
941
6.83k
    CG(map_ptr_size) = 0;
942
6.83k
    CG(map_ptr_last) = 0;
943
# else
944
#  error "Unknown ZEND_MAP_PTR_KIND"
945
# endif
946
6.83k
#endif
947
6.83k
  EG(error_reporting) = E_ALL & ~E_NOTICE;
948
949
6.83k
  zend_interned_strings_init();
950
6.83k
  zend_startup_builtin_functions();
951
6.83k
  zend_register_standard_constants();
952
6.83k
  zend_register_auto_global(zend_string_init_interned("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals);
953
954
6.83k
#ifndef ZTS
955
6.83k
  zend_init_rsrc_plist();
956
6.83k
  zend_init_exception_op();
957
6.83k
  zend_init_call_trampoline_op();
958
6.83k
#endif
959
960
6.83k
  zend_ini_startup();
961
962
#ifdef ZEND_WIN32
963
  /* Uses INI settings, so needs to be run after it. */
964
  php_win32_cp_setup();
965
#endif
966
967
#ifdef ZTS
968
  tsrm_set_new_thread_end_handler(zend_new_thread_end_handler);
969
  tsrm_set_shutdown_handler(zend_interned_strings_dtor);
970
#endif
971
6.83k
}
972
/* }}} */
973
974
void zend_register_standard_ini_entries(void) /* {{{ */
975
6.83k
{
976
6.83k
  int module_number = 0;
977
978
6.83k
  REGISTER_INI_ENTRIES();
979
6.83k
}
980
/* }}} */
981
982
0
static zend_class_entry *resolve_type_name(zend_string *type_name) {
983
0
  zend_string *lc_type_name = zend_string_tolower(type_name);
984
0
  zend_class_entry *ce = zend_hash_find_ptr(CG(class_table), lc_type_name);
985
986
0
  ZEND_ASSERT(ce && ce->type == ZEND_INTERNAL_CLASS);
987
0
  zend_string_release(lc_type_name);
988
0
  return ce;
989
0
}
990
991
static void zend_resolve_property_types(void) /* {{{ */
992
6.83k
{
993
6.83k
  zend_class_entry *ce;
994
6.83k
  zend_property_info *prop_info;
995
996
1.56M
  ZEND_HASH_FOREACH_PTR(CG(class_table), ce) {
997
778k
    if (ce->type != ZEND_INTERNAL_CLASS) {
998
0
      continue;
999
0
    }
1000
1001
778k
    if (UNEXPECTED(ZEND_CLASS_HAS_TYPE_HINTS(ce))) {
1002
2.90M
      ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
1003
2.90M
        zend_type *single_type;
1004
2.70M
        ZEND_TYPE_FOREACH(prop_info->type, single_type) {
1005
1.35M
          if (ZEND_TYPE_HAS_NAME(*single_type)) {
1006
0
            zend_string *type_name = ZEND_TYPE_NAME(*single_type);
1007
0
            ZEND_TYPE_SET_CE(*single_type, resolve_type_name(type_name));
1008
0
            zend_string_release(type_name);
1009
0
          }
1010
1.35M
        } ZEND_TYPE_FOREACH_END();
1011
1.35M
      } ZEND_HASH_FOREACH_END();
1012
198k
    }
1013
778k
    ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED;
1014
778k
  } ZEND_HASH_FOREACH_END();
1015
6.83k
}
1016
/* }}} */
1017
1018
/* Unlink the global (r/o) copies of the class, function and constant tables,
1019
 * and use a fresh r/w copy for the startup thread
1020
 */
1021
zend_result zend_post_startup(void) /* {{{ */
1022
6.83k
{
1023
#ifdef ZTS
1024
  zend_encoding **script_encoding_list;
1025
1026
  zend_compiler_globals *compiler_globals = ts_resource(compiler_globals_id);
1027
  zend_executor_globals *executor_globals = ts_resource(executor_globals_id);
1028
#endif
1029
1030
6.83k
  zend_resolve_property_types();
1031
1032
6.83k
  if (zend_post_startup_cb) {
1033
0
    zend_result (*cb)(void) = zend_post_startup_cb;
1034
1035
0
    zend_post_startup_cb = NULL;
1036
0
    if (cb() != SUCCESS) {
1037
0
      return FAILURE;
1038
0
    }
1039
6.83k
  }
1040
1041
#ifdef ZTS
1042
  *GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table;
1043
  *GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
1044
  *GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants;
1045
  global_map_ptr_last = compiler_globals->map_ptr_last;
1046
1047
  short_tags_default = CG(short_tags);
1048
  compiler_options_default = CG(compiler_options);
1049
1050
  zend_destroy_rsrc_list(&EG(persistent_list));
1051
  free(compiler_globals->function_table);
1052
  compiler_globals->function_table = NULL;
1053
  free(compiler_globals->class_table);
1054
  compiler_globals->class_table = NULL;
1055
  if (ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base)) {
1056
    free(ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base));
1057
  }
1058
  ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL);
1059
  if ((script_encoding_list = (zend_encoding **)compiler_globals->script_encoding_list)) {
1060
    compiler_globals_ctor(compiler_globals);
1061
    compiler_globals->script_encoding_list = (const zend_encoding **)script_encoding_list;
1062
  } else {
1063
    compiler_globals_ctor(compiler_globals);
1064
  }
1065
  free(EG(zend_constants));
1066
  EG(zend_constants) = NULL;
1067
1068
  executor_globals_ctor(executor_globals);
1069
  global_persistent_list = &EG(persistent_list);
1070
  zend_copy_ini_directives();
1071
#else
1072
6.83k
  global_map_ptr_last = CG(map_ptr_last);
1073
6.83k
#endif
1074
1075
6.83k
  return SUCCESS;
1076
6.83k
}
1077
/* }}} */
1078
1079
void zend_shutdown(void) /* {{{ */
1080
0
{
1081
0
  zend_vm_dtor();
1082
1083
0
  zend_destroy_rsrc_list(&EG(persistent_list));
1084
0
  zend_destroy_modules();
1085
1086
0
  virtual_cwd_deactivate();
1087
0
  virtual_cwd_shutdown();
1088
1089
0
  zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
1090
0
  zend_hash_destroy(GLOBAL_CLASS_TABLE);
1091
1092
0
  zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
1093
0
  free(GLOBAL_AUTO_GLOBALS_TABLE);
1094
1095
0
  zend_shutdown_error_notify_callbacks();
1096
0
  zend_shutdown_extensions();
1097
0
  free(zend_version_info);
1098
1099
0
  free(GLOBAL_FUNCTION_TABLE);
1100
0
  free(GLOBAL_CLASS_TABLE);
1101
1102
0
  zend_hash_destroy(GLOBAL_CONSTANTS_TABLE);
1103
0
  free(GLOBAL_CONSTANTS_TABLE);
1104
0
  zend_shutdown_strtod();
1105
0
  zend_attributes_shutdown();
1106
1107
#ifdef ZTS
1108
  GLOBAL_FUNCTION_TABLE = NULL;
1109
  GLOBAL_CLASS_TABLE = NULL;
1110
  GLOBAL_AUTO_GLOBALS_TABLE = NULL;
1111
  GLOBAL_CONSTANTS_TABLE = NULL;
1112
  ts_free_id(executor_globals_id);
1113
  ts_free_id(compiler_globals_id);
1114
#else
1115
0
  if (ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base))) {
1116
0
    free(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)));
1117
0
    ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), NULL);
1118
0
    CG(map_ptr_size) = 0;
1119
0
  }
1120
0
  if (CG(script_encoding_list)) {
1121
0
    free(ZEND_VOIDP(CG(script_encoding_list)));
1122
0
    CG(script_encoding_list) = NULL;
1123
0
    CG(script_encoding_list_size) = 0;
1124
0
  }
1125
0
#endif
1126
0
  zend_destroy_rsrc_list_dtors();
1127
0
}
1128
/* }}} */
1129
1130
void zend_set_utility_values(zend_utility_values *utility_values) /* {{{ */
1131
6.83k
{
1132
6.83k
  zend_uv = *utility_values;
1133
6.83k
}
1134
/* }}} */
1135
1136
/* this should be compatible with the standard zenderror */
1137
ZEND_COLD void zenderror(const char *error) /* {{{ */
1138
115k
{
1139
115k
  CG(parse_error) = 0;
1140
1141
115k
  if (EG(exception)) {
1142
    /* An exception was thrown in the lexer, don't throw another in the parser. */
1143
10.7k
    return;
1144
10.7k
  }
1145
1146
104k
  zend_throw_exception(zend_ce_parse_error, error, 0);
1147
104k
}
1148
/* }}} */
1149
1150
BEGIN_EXTERN_C()
1151
ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32_t lineno) /* {{{ */
1152
25.1k
{
1153
1154
25.1k
  if (!EG(bailout)) {
1155
0
    zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", filename, lineno);
1156
0
    exit(-1);
1157
0
  }
1158
25.1k
  gc_protect(1);
1159
25.1k
  CG(unclean_shutdown) = 1;
1160
25.1k
  CG(active_class_entry) = NULL;
1161
25.1k
  CG(in_compilation) = 0;
1162
25.1k
  EG(current_execute_data) = NULL;
1163
25.1k
  LONGJMP(*EG(bailout), FAILURE);
1164
25.1k
}
1165
/* }}} */
1166
END_EXTERN_C()
1167
1168
ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ */
1169
0
{
1170
0
  char *new_info;
1171
0
  uint32_t new_info_length;
1172
1173
0
  new_info_length = (uint32_t)(sizeof("    with  v, , by \n")
1174
0
            + strlen(extension->name)
1175
0
            + strlen(extension->version)
1176
0
            + strlen(extension->copyright)
1177
0
            + strlen(extension->author));
1178
1179
0
  new_info = (char *) malloc(new_info_length + 1);
1180
1181
0
  snprintf(new_info, new_info_length, "    with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author);
1182
1183
0
  zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length + 1);
1184
0
  strncat(zend_version_info, new_info, new_info_length);
1185
0
  zend_version_info_length += new_info_length;
1186
0
  free(new_info);
1187
0
}
1188
/* }}} */
1189
1190
ZEND_API const char *get_zend_version(void) /* {{{ */
1191
20
{
1192
20
  return zend_version_info;
1193
20
}
1194
/* }}} */
1195
1196
ZEND_API void zend_activate(void) /* {{{ */
1197
647k
{
1198
#ifdef ZTS
1199
  virtual_cwd_activate();
1200
#endif
1201
647k
  gc_reset();
1202
647k
  init_compiler();
1203
647k
  init_executor();
1204
647k
  startup_scanner();
1205
647k
  if (CG(map_ptr_last)) {
1206
0
    memset(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), 0, CG(map_ptr_last) * sizeof(void*));
1207
0
  }
1208
647k
}
1209
/* }}} */
1210
1211
void zend_call_destructors(void) /* {{{ */
1212
643k
{
1213
643k
  zend_try {
1214
643k
    shutdown_destructors();
1215
643k
  } zend_end_try();
1216
643k
}
1217
/* }}} */
1218
1219
ZEND_API void zend_deactivate(void) /* {{{ */
1220
643k
{
1221
  /* we're no longer executing anything */
1222
643k
  EG(current_execute_data) = NULL;
1223
1224
643k
  zend_try {
1225
643k
    shutdown_scanner();
1226
643k
  } zend_end_try();
1227
1228
  /* shutdown_executor() takes care of its own bailout handling */
1229
643k
  shutdown_executor();
1230
1231
643k
  zend_try {
1232
643k
    zend_ini_deactivate();
1233
643k
  } zend_end_try();
1234
1235
643k
  zend_try {
1236
643k
    shutdown_compiler();
1237
643k
  } zend_end_try();
1238
1239
643k
  zend_destroy_rsrc_list(&EG(regular_list));
1240
1241
#if GC_BENCH
1242
  fprintf(stderr, "GC Statistics\n");
1243
  fprintf(stderr, "-------------\n");
1244
  fprintf(stderr, "Runs:               %d\n", GC_G(gc_runs));
1245
  fprintf(stderr, "Collected:          %d\n", GC_G(collected));
1246
  fprintf(stderr, "Root buffer length: %d\n", GC_G(root_buf_length));
1247
  fprintf(stderr, "Root buffer peak:   %d\n\n", GC_G(root_buf_peak));
1248
  fprintf(stderr, "      Possible            Remove from  Marked\n");
1249
  fprintf(stderr, "        Root    Buffered     buffer     grey\n");
1250
  fprintf(stderr, "      --------  --------  -----------  ------\n");
1251
  fprintf(stderr, "ZVAL  %8d  %8d  %9d  %8d\n", GC_G(zval_possible_root), GC_G(zval_buffered), GC_G(zval_remove_from_buffer), GC_G(zval_marked_grey));
1252
#endif
1253
643k
}
1254
/* }}} */
1255
1256
BEGIN_EXTERN_C()
1257
ZEND_API void zend_message_dispatcher(zend_long message, const void *data) /* {{{ */
1258
20.7k
{
1259
20.7k
  if (zend_message_dispatcher_p) {
1260
20.7k
    zend_message_dispatcher_p(message, data);
1261
20.7k
  }
1262
20.7k
}
1263
/* }}} */
1264
END_EXTERN_C()
1265
1266
ZEND_API zval *zend_get_configuration_directive(zend_string *name) /* {{{ */
1267
874k
{
1268
874k
  if (zend_get_configuration_directive_p) {
1269
874k
    return zend_get_configuration_directive_p(name);
1270
0
  } else {
1271
0
    return NULL;
1272
0
  }
1273
874k
}
1274
/* }}} */
1275
1276
206
#define SAVE_STACK(stack) do { \
1277
206
    if (CG(stack).top) { \
1278
55
      memcpy(&stack, &CG(stack), sizeof(zend_stack)); \
1279
55
      CG(stack).top = CG(stack).max = 0; \
1280
55
      CG(stack).elements = NULL; \
1281
151
    } else { \
1282
151
      stack.top = 0; \
1283
151
    } \
1284
206
  } while (0)
1285
1286
206
#define RESTORE_STACK(stack) do { \
1287
206
    if (stack.top) { \
1288
55
      zend_stack_destroy(&CG(stack)); \
1289
55
      memcpy(&CG(stack), &stack, sizeof(zend_stack)); \
1290
55
    } \
1291
206
  } while (0)
1292
1293
static ZEND_COLD void zend_error_impl(
1294
    int orig_type, const char *error_filename, uint32_t error_lineno, zend_string *message)
1295
2.29M
{
1296
2.29M
  zval params[4];
1297
2.29M
  zval retval;
1298
2.29M
  zval orig_user_error_handler;
1299
2.29M
  zend_bool in_compilation;
1300
2.29M
  zend_class_entry *saved_class_entry;
1301
2.29M
  zend_stack loop_var_stack;
1302
2.29M
  zend_stack delayed_oplines_stack;
1303
2.29M
  int type = orig_type & E_ALL;
1304
1305
  /* Report about uncaught exception in case of fatal errors */
1306
2.29M
  if (EG(exception)) {
1307
875
    zend_execute_data *ex;
1308
875
    const zend_op *opline;
1309
1310
875
    switch (type) {
1311
0
      case E_CORE_ERROR:
1312
25
      case E_ERROR:
1313
25
      case E_RECOVERABLE_ERROR:
1314
25
      case E_PARSE:
1315
66
      case E_COMPILE_ERROR:
1316
66
      case E_USER_ERROR:
1317
66
        ex = EG(current_execute_data);
1318
66
        opline = NULL;
1319
71
        while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
1320
5
          ex = ex->prev_execute_data;
1321
5
        }
1322
66
        if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
1323
61
            EG(opline_before_exception)) {
1324
61
          opline = EG(opline_before_exception);
1325
61
        }
1326
66
        zend_exception_error(EG(exception), E_WARNING);
1327
66
        EG(exception) = NULL;
1328
66
        if (opline) {
1329
61
          ex->opline = opline;
1330
61
        }
1331
66
        break;
1332
809
      default:
1333
809
        break;
1334
2.29M
    }
1335
2.29M
  }
1336
1337
2.29M
  zend_error_notify_all_callbacks(type, error_filename, error_lineno, message);
1338
1339
  /* if we don't have a user defined error handler */
1340
2.29M
  if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
1341
20.3k
    || !(EG(user_error_handler_error_reporting) & type)
1342
2.27M
    || EG(error_handling) != EH_NORMAL) {
1343
2.27M
    zend_error_cb(orig_type, error_filename, error_lineno, message);
1344
20.3k
  } else switch (type) {
1345
7
    case E_ERROR:
1346
7
    case E_PARSE:
1347
7
    case E_CORE_ERROR:
1348
7
    case E_CORE_WARNING:
1349
22
    case E_COMPILE_ERROR:
1350
22
    case E_COMPILE_WARNING:
1351
      /* The error may not be safe to handle in user-space */
1352
22
      zend_error_cb(orig_type, error_filename, error_lineno, message);
1353
22
      break;
1354
20.2k
    default:
1355
      /* Handle the error in user space */
1356
20.2k
      ZVAL_STR_COPY(&params[1], message);
1357
20.2k
      ZVAL_LONG(&params[0], type);
1358
1359
20.2k
      if (error_filename) {
1360
20.2k
        ZVAL_STRING(&params[2], error_filename);
1361
0
      } else {
1362
0
        ZVAL_NULL(&params[2]);
1363
0
      }
1364
1365
20.2k
      ZVAL_LONG(&params[3], error_lineno);
1366
1367
20.2k
      ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));
1368
20.2k
      ZVAL_UNDEF(&EG(user_error_handler));
1369
1370
      /* User error handler may include() additinal PHP files.
1371
       * If an error was generated during comilation PHP will compile
1372
       * such scripts recursively, but some CG() variables may be
1373
       * inconsistent. */
1374
1375
20.2k
      in_compilation = CG(in_compilation);
1376
20.2k
      if (in_compilation) {
1377
103
        saved_class_entry = CG(active_class_entry);
1378
103
        CG(active_class_entry) = NULL;
1379
103
        SAVE_STACK(loop_var_stack);
1380
103
        SAVE_STACK(delayed_oplines_stack);
1381
103
        CG(in_compilation) = 0;
1382
103
      }
1383
1384
20.2k
      if (call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params) == SUCCESS) {
1385
20.1k
        if (Z_TYPE(retval) != IS_UNDEF) {
1386
17.6k
          if (Z_TYPE(retval) == IS_FALSE) {
1387
52
            zend_error_cb(orig_type, error_filename, error_lineno, message);
1388
52
          }
1389
17.6k
          zval_ptr_dtor(&retval);
1390
17.6k
        }
1391
189
      } else if (!EG(exception)) {
1392
        /* The user error handler failed, use built-in error handler */
1393
0
        zend_error_cb(orig_type, error_filename, error_lineno, message);
1394
0
      }
1395
1396
20.2k
      if (in_compilation) {
1397
103
        CG(active_class_entry) = saved_class_entry;
1398
103
        RESTORE_STACK(loop_var_stack);
1399
103
        RESTORE_STACK(delayed_oplines_stack);
1400
103
        CG(in_compilation) = 1;
1401
103
      }
1402
1403
20.2k
      zval_ptr_dtor(&params[2]);
1404
20.2k
      zval_ptr_dtor(&params[1]);
1405
1406
20.2k
      if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF) {
1407
20.2k
        ZVAL_COPY_VALUE(&EG(user_error_handler), &orig_user_error_handler);
1408
77
      } else {
1409
77
        zval_ptr_dtor(&orig_user_error_handler);
1410
77
      }
1411
20.2k
      break;
1412
2.29M
  }
1413
1414
2.29M
  if (type == E_PARSE) {
1415
    /* eval() errors do not affect exit_status */
1416
0
    if (!(EG(current_execute_data) &&
1417
0
      EG(current_execute_data)->func &&
1418
0
      ZEND_USER_CODE(EG(current_execute_data)->func->type) &&
1419
0
      EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
1420
0
      EG(current_execute_data)->opline->extended_value == ZEND_EVAL)) {
1421
0
      EG(exit_status) = 255;
1422
0
    }
1423
0
  }
1424
2.29M
}
1425
/* }}} */
1426
1427
static ZEND_COLD void zend_error_va_list(
1428
    int orig_type, const char *error_filename, uint32_t error_lineno,
1429
    const char *format, va_list args)
1430
1.88M
{
1431
1.88M
  zend_string *message = zend_vstrpprintf(0, format, args);
1432
1.88M
  zend_error_impl(orig_type, error_filename, error_lineno, message);
1433
1.88M
  zend_string_release(message);
1434
1.88M
}
1435
1436
2.29M
static ZEND_COLD void get_filename_lineno(int type, const char **filename, uint32_t *lineno) {
1437
  /* Obtain relevant filename and lineno */
1438
2.29M
  switch (type) {
1439
26
    case E_CORE_ERROR:
1440
26
    case E_CORE_WARNING:
1441
26
      *filename = NULL;
1442
26
      *lineno = 0;
1443
26
      break;
1444
0
    case E_PARSE:
1445
12.6k
    case E_COMPILE_ERROR:
1446
14.8k
    case E_COMPILE_WARNING:
1447
16.0k
    case E_ERROR:
1448
26.1k
    case E_NOTICE:
1449
26.1k
    case E_STRICT:
1450
26.5k
    case E_DEPRECATED:
1451
2.29M
    case E_WARNING:
1452
2.29M
    case E_USER_ERROR:
1453
2.29M
    case E_USER_WARNING:
1454
2.29M
    case E_USER_NOTICE:
1455
2.29M
    case E_USER_DEPRECATED:
1456
2.29M
    case E_RECOVERABLE_ERROR:
1457
2.29M
      if (zend_is_compiling()) {
1458
13.1k
        *filename = ZSTR_VAL(zend_get_compiled_filename());
1459
13.1k
        *lineno = zend_get_compiled_lineno();
1460
2.28M
      } else if (zend_is_executing()) {
1461
2.28M
        *filename = zend_get_executed_filename();
1462
2.28M
        if ((*filename)[0] == '[') { /* [no active file] */
1463
0
          *filename = NULL;
1464
0
          *lineno = 0;
1465
2.28M
        } else {
1466
2.28M
          *lineno = zend_get_executed_lineno();
1467
2.28M
        }
1468
31
      } else {
1469
31
        *filename = NULL;
1470
31
        *lineno = 0;
1471
31
      }
1472
2.29M
      break;
1473
0
    default:
1474
0
      *filename = NULL;
1475
0
      *lineno = 0;
1476
0
      break;
1477
2.29M
  }
1478
2.29M
  if (!*filename) {
1479
57
    *filename = "Unknown";
1480
57
  }
1481
2.29M
}
1482
1483
ZEND_API ZEND_COLD void zend_error_at(
1484
2.52k
    int type, const char *filename, uint32_t lineno, const char *format, ...) {
1485
2.52k
  va_list args;
1486
1487
2.52k
  if (!filename) {
1488
2.52k
    uint32_t dummy_lineno;
1489
2.52k
    get_filename_lineno(type, &filename, &dummy_lineno);
1490
2.52k
  }
1491
1492
2.52k
  va_start(args, format);
1493
2.52k
  zend_error_va_list(type, filename, lineno, format, args);
1494
2.52k
  va_end(args);
1495
2.52k
}
1496
1497
1.87M
ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) {
1498
1.87M
  const char *filename;
1499
1.87M
  uint32_t lineno;
1500
1.87M
  va_list args;
1501
1502
1.87M
  get_filename_lineno(type, &filename, &lineno);
1503
1.87M
  va_start(args, format);
1504
1.87M
  zend_error_va_list(type, filename, lineno, format, args);
1505
1.87M
  va_end(args);
1506
1.87M
}
1507
1508
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn(
1509
    int type, const char *filename, uint32_t lineno, const char *format, ...)
1510
187
{
1511
187
  va_list args;
1512
1513
187
  if (!filename) {
1514
187
    uint32_t dummy_lineno;
1515
187
    get_filename_lineno(type, &filename, &dummy_lineno);
1516
187
  }
1517
1518
187
  va_start(args, format);
1519
187
  zend_error_va_list(type, filename, lineno, format, args);
1520
187
  va_end(args);
1521
  /* Should never reach this. */
1522
187
  abort();
1523
187
}
1524
1525
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...)
1526
9.65k
{
1527
9.65k
  const char *filename;
1528
9.65k
  uint32_t lineno;
1529
9.65k
  va_list args;
1530
1531
9.65k
  get_filename_lineno(type, &filename, &lineno);
1532
9.65k
  va_start(args, format);
1533
9.65k
  zend_error_va_list(type, filename, lineno, format, args);
1534
9.65k
  va_end(args);
1535
  /* Should never reach this. */
1536
9.65k
  abort();
1537
9.65k
}
1538
1539
407k
ZEND_API ZEND_COLD void zend_error_zstr(int type, zend_string *message) {
1540
407k
  const char *filename;
1541
407k
  uint32_t lineno;
1542
407k
  get_filename_lineno(type, &filename, &lineno);
1543
407k
  zend_error_impl(type, filename, lineno, message);
1544
407k
}
1545
1546
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
1547
191k
{
1548
191k
  va_list va;
1549
191k
  char *message = NULL;
1550
1551
191k
  if (!exception_ce) {
1552
184k
    exception_ce = zend_ce_error;
1553
184k
  }
1554
1555
  /* Marker used to disable exception generation during preloading. */
1556
191k
  if (EG(exception) == (void*)(uintptr_t)-1) {
1557
0
    return;
1558
0
  }
1559
1560
191k
  va_start(va, format);
1561
191k
  zend_vspprintf(&message, 0, format, va);
1562
1563
  //TODO: we can't convert compile-time errors to exceptions yet???
1564
191k
  if (EG(current_execute_data) && !CG(in_compilation)) {
1565
191k
    zend_throw_exception(exception_ce, message, 0);
1566
56
  } else {
1567
56
    zend_error(E_ERROR, "%s", message);
1568
56
  }
1569
1570
191k
  efree(message);
1571
191k
  va_end(va);
1572
191k
}
1573
/* }}} */
1574
1575
ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) /* {{{ */
1576
67.7k
{
1577
67.7k
  va_list va;
1578
67.7k
  char *message = NULL;
1579
1580
67.7k
  va_start(va, format);
1581
67.7k
  zend_vspprintf(&message, 0, format, va);
1582
67.7k
  zend_throw_exception(zend_ce_type_error, message, 0);
1583
67.7k
  efree(message);
1584
67.7k
  va_end(va);
1585
67.7k
} /* }}} */
1586
1587
ZEND_API ZEND_COLD void zend_argument_count_error(const char *format, ...) /* {{{ */
1588
6.50k
{
1589
6.50k
  va_list va;
1590
6.50k
  char *message = NULL;
1591
1592
6.50k
  va_start(va, format);
1593
6.50k
  zend_vspprintf(&message, 0, format, va);
1594
6.50k
  zend_throw_exception(zend_ce_argument_count_error, message, 0);
1595
6.50k
  efree(message);
1596
1597
6.50k
  va_end(va);
1598
6.50k
} /* }}} */
1599
1600
ZEND_API ZEND_COLD void zend_value_error(const char *format, ...) /* {{{ */
1601
328
{
1602
328
  va_list va;
1603
328
  char *message = NULL;
1604
1605
328
  va_start(va, format);
1606
328
  zend_vspprintf(&message, 0, format, va);
1607
328
  zend_throw_exception(zend_ce_value_error, message, 0);
1608
328
  efree(message);
1609
328
  va_end(va);
1610
328
} /* }}} */
1611
1612
ZEND_API ZEND_COLD void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) /* {{{ */
1613
0
{
1614
0
#if ZEND_DEBUG
1615
0
  va_list args;
1616
1617
0
  va_start(args, format);
1618
# ifdef ZEND_WIN32
1619
  {
1620
    char output_buf[1024];
1621
1622
    vsnprintf(output_buf, 1024, format, args);
1623
    OutputDebugString(output_buf);
1624
    OutputDebugString("\n");
1625
    if (trigger_break && IsDebuggerPresent()) {
1626
      DebugBreak();
1627
    }
1628
  }
1629
# else
1630
0
  vfprintf(stderr, format, args);
1631
0
  fprintf(stderr, "\n");
1632
0
# endif
1633
0
  va_end(args);
1634
0
#endif
1635
0
}
1636
/* }}} */
1637
1638
ZEND_API ZEND_COLD void zend_user_exception_handler(void) /* {{{ */
1639
0
{
1640
0
  zval orig_user_exception_handler;
1641
0
  zval params[1], retval2;
1642
0
  zend_object *old_exception;
1643
1644
0
  if (zend_is_unwind_exit(EG(exception))) {
1645
0
    return;
1646
0
  }
1647
1648
0
  old_exception = EG(exception);
1649
0
  EG(exception) = NULL;
1650
0
  ZVAL_OBJ(&params[0], old_exception);
1651
0
  ZVAL_COPY_VALUE(&orig_user_exception_handler, &EG(user_exception_handler));
1652
1653
0
  if (call_user_function(CG(function_table), NULL, &orig_user_exception_handler, &retval2, 1, params) == SUCCESS) {
1654
0
    zval_ptr_dtor(&retval2);
1655
0
    if (EG(exception)) {
1656
0
      OBJ_RELEASE(EG(exception));
1657
0
      EG(exception) = NULL;
1658
0
    }
1659
0
    OBJ_RELEASE(old_exception);
1660
0
  } else {
1661
0
    EG(exception) = old_exception;
1662
0
  }
1663
0
} /* }}} */
1664
1665
ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count, ...) /* {{{ */
1666
0
{
1667
0
  va_list files;
1668
0
  int i;
1669
0
  zend_file_handle *file_handle;
1670
0
  zend_op_array *op_array;
1671
0
  zend_result ret = SUCCESS;
1672
1673
0
  va_start(files, file_count);
1674
0
  for (i = 0; i < file_count; i++) {
1675
0
    file_handle = va_arg(files, zend_file_handle *);
1676
0
    if (!file_handle) {
1677
0
      continue;
1678
0
    }
1679
1680
0
    if (ret == FAILURE) {
1681
      /* If a failure occurred in one of the earlier files,
1682
       * only destroy the following file handles. */
1683
0
      zend_file_handle_dtor(file_handle);
1684
0
      continue;
1685
0
    }
1686
1687
0
    op_array = zend_compile_file(file_handle, type);
1688
0
    if (file_handle->opened_path) {
1689
0
      zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path);
1690
0
    }
1691
0
    zend_destroy_file_handle(file_handle);
1692
0
    if (op_array) {
1693
0
      zend_execute(op_array, retval);
1694
0
      zend_exception_restore();
1695
0
      if (UNEXPECTED(EG(exception))) {
1696
0
        if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
1697
0
          zend_user_exception_handler();
1698
0
        }
1699
0
        if (EG(exception)) {
1700
0
          ret = zend_exception_error(EG(exception), E_ERROR);
1701
0
        }
1702
0
      }
1703
0
      destroy_op_array(op_array);
1704
0
      efree_size(op_array, sizeof(zend_op_array));
1705
0
    } else if (type==ZEND_REQUIRE) {
1706
0
      ret = FAILURE;
1707
0
    }
1708
0
  }
1709
0
  va_end(files);
1710
1711
0
  return ret;
1712
0
}
1713
/* }}} */
1714
1715
32.9k
#define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%d) : %s"
1716
1717
ZEND_API char *zend_make_compiled_string_description(const char *name) /* {{{ */
1718
32.9k
{
1719
32.9k
  const char *cur_filename;
1720
32.9k
  int cur_lineno;
1721
32.9k
  char *compiled_string_description;
1722
1723
32.9k
  if (zend_is_compiling()) {
1724
0
    cur_filename = ZSTR_VAL(zend_get_compiled_filename());
1725
0
    cur_lineno = zend_get_compiled_lineno();
1726
32.9k
  } else if (zend_is_executing()) {
1727
32.9k
    cur_filename = zend_get_executed_filename();
1728
32.9k
    cur_lineno = zend_get_executed_lineno();
1729
0
  } else {
1730
0
    cur_filename = "Unknown";
1731
0
    cur_lineno = 0;
1732
0
  }
1733
1734
32.9k
  zend_spprintf(&compiled_string_description, 0, COMPILED_STRING_DESCRIPTION_FORMAT, cur_filename, cur_lineno, name);
1735
32.9k
  return compiled_string_description;
1736
32.9k
}
1737
/* }}} */
1738
1739
void free_estring(char **str_p) /* {{{ */
1740
0
{
1741
0
  efree(*str_p);
1742
0
}
1743
/* }}} */
1744
1745
ZEND_API void zend_map_ptr_reset(void)
1746
0
{
1747
0
  CG(map_ptr_last) = global_map_ptr_last;
1748
0
}
1749
1750
ZEND_API void *zend_map_ptr_new(void)
1751
0
{
1752
0
  void **ptr;
1753
1754
0
  if (CG(map_ptr_last) >= CG(map_ptr_size)) {
1755
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
1756
    // TODO: error ???
1757
    ZEND_UNREACHABLE();
1758
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
1759
    /* Grow map_ptr table */
1760
0
    CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096);
1761
0
    ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), perealloc(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), CG(map_ptr_size) * sizeof(void*), 1));
1762
#else
1763
# error "Unknown ZEND_MAP_PTR_KIND"
1764
#endif
1765
0
  }
1766
0
  ptr = (void**)ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)) + CG(map_ptr_last);
1767
0
  *ptr = NULL;
1768
0
  CG(map_ptr_last)++;
1769
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
1770
  return ptr;
1771
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
1772
0
  return ZEND_MAP_PTR_PTR2OFFSET(ptr);
1773
#else
1774
# error "Unknown ZEND_MAP_PTR_KIND"
1775
#endif
1776
0
}
1777
1778
ZEND_API void zend_map_ptr_extend(size_t last)
1779
0
{
1780
0
  if (last > CG(map_ptr_last)) {
1781
0
    void **ptr;
1782
1783
0
    if (last >= CG(map_ptr_size)) {
1784
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
1785
      /* This may never happen */
1786
      ZEND_UNREACHABLE();
1787
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
1788
      /* Grow map_ptr table */
1789
0
      CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(last, 4096);
1790
0
      ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), perealloc(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), CG(map_ptr_size) * sizeof(void*), 1));
1791
#else
1792
# error "Unknown ZEND_MAP_PTR_KIND"
1793
#endif
1794
0
    }
1795
0
    ptr = (void**)ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)) + CG(map_ptr_last);
1796
0
    memset(ptr, 0, (last - CG(map_ptr_last)) * sizeof(void*));
1797
0
    CG(map_ptr_last) = last;
1798
0
  }
1799
0
}
1800
1801
void zend_startup_error_notify_callbacks(void)
1802
6.83k
{
1803
6.83k
  zend_llist_init(&zend_error_notify_callbacks, sizeof(zend_error_notify_cb), NULL, 1);
1804
6.83k
}
1805
1806
void zend_shutdown_error_notify_callbacks(void)
1807
0
{
1808
0
  zend_llist_destroy(&zend_error_notify_callbacks);
1809
0
}
1810
1811
ZEND_API void zend_register_error_notify_callback(zend_error_notify_cb cb)
1812
6.83k
{
1813
6.83k
  zend_llist_add_element(&zend_error_notify_callbacks, &cb);
1814
6.83k
}
1815
1816
void zend_error_notify_all_callbacks(int type, const char *error_filename, uint32_t error_lineno, zend_string *message)
1817
2.29M
{
1818
2.29M
  zend_llist_element *element;
1819
2.29M
  zend_error_notify_cb callback;
1820
1821
4.59M
  for (element = zend_error_notify_callbacks.head; element; element = element->next) {
1822
2.29M
    callback = *(zend_error_notify_cb *) (element->data);
1823
2.29M
    callback(type, error_filename, error_lineno, message);
1824
2.29M
  }
1825
2.29M
}