Coverage Report

Created: 2025-11-16 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/Zend/zend_execute_API.c
Line
Count
Source
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
   |          Dmitry Stogov <dmitry@php.net>                              |
18
   +----------------------------------------------------------------------+
19
*/
20
21
#include <stdio.h>
22
#include <signal.h>
23
24
#include "zend.h"
25
#include "zend_compile.h"
26
#include "zend_execute.h"
27
#include "zend_API.h"
28
#include "zend_stack.h"
29
#include "zend_constants.h"
30
#include "zend_extensions.h"
31
#include "zend_exceptions.h"
32
#include "zend_closures.h"
33
#include "zend_generators.h"
34
#include "zend_vm.h"
35
#include "zend_float.h"
36
#include "zend_fibers.h"
37
#include "zend_weakrefs.h"
38
#include "zend_inheritance.h"
39
#include "zend_observer.h"
40
#include "zend_call_stack.h"
41
#include "zend_frameless_function.h"
42
#ifdef HAVE_SYS_TIME_H
43
#include <sys/time.h>
44
#endif
45
#ifdef HAVE_UNISTD_H
46
#include <unistd.h>
47
#endif
48
#ifdef ZEND_MAX_EXECUTION_TIMERS
49
#include <sys/syscall.h>
50
#endif
51
52
ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data);
53
ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value);
54
ZEND_API zend_class_entry *(*zend_autoload)(zend_string *name, zend_string *lc_name);
55
56
#ifdef ZEND_WIN32
57
ZEND_TLS HANDLE tq_timer = NULL;
58
#endif
59
60
#if 0&&ZEND_DEBUG
61
static void (*original_sigsegv_handler)(int);
62
static void zend_handle_sigsegv(void) /* {{{ */
63
{
64
  fflush(stdout);
65
  fflush(stderr);
66
  if (original_sigsegv_handler == zend_handle_sigsegv) {
67
    signal(SIGSEGV, original_sigsegv_handler);
68
  } else {
69
    signal(SIGSEGV, SIG_DFL);
70
  }
71
  {
72
73
    fprintf(stderr, "SIGSEGV caught on opcode %d on opline %d of %s() at %s:%d\n\n",
74
        active_opline->opcode,
75
        active_opline-EG(active_op_array)->opcodes,
76
        get_active_function_name(),
77
        zend_get_executed_filename(),
78
        zend_get_executed_lineno());
79
/* See http://support.microsoft.com/kb/190351 */
80
#ifdef ZEND_WIN32
81
    fflush(stderr);
82
#endif
83
  }
84
  if (original_sigsegv_handler!=zend_handle_sigsegv) {
85
    original_sigsegv_handler(dummy);
86
  }
87
}
88
/* }}} */
89
#endif
90
91
static void zend_extension_activator(const zend_extension *extension) /* {{{ */
92
247k
{
93
247k
  if (extension->activate) {
94
247k
    extension->activate();
95
247k
  }
96
247k
}
97
/* }}} */
98
99
static void zend_extension_deactivator(const zend_extension *extension) /* {{{ */
100
247k
{
101
247k
  if (extension->deactivate) {
102
247k
    extension->deactivate();
103
247k
  }
104
247k
}
105
/* }}} */
106
107
static int clean_non_persistent_constant_full(zval *zv) /* {{{ */
108
0
{
109
0
  zend_constant *c = Z_PTR_P(zv);
110
0
  return (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
111
0
}
112
/* }}} */
113
114
static int clean_non_persistent_function_full(zval *zv) /* {{{ */
115
0
{
116
0
  const zend_function *function = Z_PTR_P(zv);
117
0
  return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
118
0
}
119
/* }}} */
120
121
static int clean_non_persistent_class_full(zval *zv) /* {{{ */
122
0
{
123
0
  const zend_class_entry *ce = Z_PTR_P(zv);
124
0
  return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
125
0
}
126
/* }}} */
127
128
void init_executor(void) /* {{{ */
129
247k
{
130
247k
  zend_init_fpu();
131
132
247k
  ZVAL_NULL(&EG(uninitialized_zval));
133
247k
  ZVAL_ERROR(&EG(error_zval));
134
/* destroys stack frame, therefore makes core dumps worthless */
135
#if 0&&ZEND_DEBUG
136
  original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv);
137
#endif
138
139
247k
  ZVAL_UNDEF(&EG(last_fatal_error_backtrace));
140
141
247k
  EG(symtable_cache_ptr) = EG(symtable_cache);
142
247k
  EG(symtable_cache_limit) = EG(symtable_cache) + SYMTABLE_CACHE_SIZE;
143
247k
  EG(no_extensions) = 0;
144
145
247k
  EG(function_table) = CG(function_table);
146
247k
  EG(class_table) = CG(class_table);
147
148
247k
  EG(in_autoload) = NULL;
149
247k
  EG(error_handling) = EH_NORMAL;
150
247k
  EG(flags) = EG_FLAGS_INITIAL;
151
152
247k
  zend_vm_stack_init();
153
154
247k
  zend_hash_init(&EG(symbol_table), 64, NULL, ZVAL_PTR_DTOR, 0);
155
156
247k
  zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator);
157
158
247k
  zend_hash_init(&EG(included_files), 8, NULL, NULL, 0);
159
160
247k
  EG(ticks_count) = 0;
161
162
247k
  ZVAL_UNDEF(&EG(user_error_handler));
163
247k
  ZVAL_UNDEF(&EG(user_exception_handler));
164
165
247k
  EG(current_execute_data) = NULL;
166
167
247k
  zend_stack_init(&EG(user_error_handlers_error_reporting), sizeof(int));
168
247k
  zend_stack_init(&EG(user_error_handlers), sizeof(zval));
169
247k
  zend_stack_init(&EG(user_exception_handlers), sizeof(zval));
170
171
247k
  zend_objects_store_init(&EG(objects_store), 1024);
172
247k
  zend_lazy_objects_init(&EG(lazy_objects_store));
173
174
247k
  EG(full_tables_cleanup) = 0;
175
247k
  ZEND_ATOMIC_BOOL_INIT(&EG(vm_interrupt), false);
176
247k
  ZEND_ATOMIC_BOOL_INIT(&EG(timed_out), false);
177
178
247k
  EG(exception) = NULL;
179
247k
  EG(prev_exception) = NULL;
180
181
247k
  EG(fake_scope) = NULL;
182
247k
  EG(trampoline).common.function_name = NULL;
183
184
247k
  EG(ht_iterators_count) = sizeof(EG(ht_iterators_slots)) / sizeof(HashTableIterator);
185
247k
  EG(ht_iterators_used) = 0;
186
247k
  EG(ht_iterators) = EG(ht_iterators_slots);
187
247k
  memset(EG(ht_iterators), 0, sizeof(EG(ht_iterators_slots)));
188
189
247k
  EG(persistent_constants_count) = EG(zend_constants)->nNumUsed;
190
247k
  EG(persistent_functions_count) = EG(function_table)->nNumUsed;
191
247k
  EG(persistent_classes_count)   = EG(class_table)->nNumUsed;
192
193
247k
  EG(get_gc_buffer).start = EG(get_gc_buffer).end = EG(get_gc_buffer).cur = NULL;
194
195
247k
  EG(record_errors) = false;
196
247k
  EG(num_errors) = 0;
197
247k
  EG(errors) = NULL;
198
199
247k
  EG(filename_override) = NULL;
200
247k
  EG(lineno_override) = -1;
201
202
247k
  zend_max_execution_timer_init();
203
247k
  zend_fiber_init();
204
247k
  zend_weakrefs_init();
205
206
247k
  zend_hash_init(&EG(callable_convert_cache), 8, NULL, ZVAL_PTR_DTOR, 0);
207
208
247k
  EG(active) = 1;
209
247k
}
210
/* }}} */
211
212
static int zval_call_destructor(zval *zv) /* {{{ */
213
1.56M
{
214
1.56M
  if (Z_TYPE_P(zv) == IS_INDIRECT) {
215
220k
    zv = Z_INDIRECT_P(zv);
216
220k
  }
217
1.56M
  if (Z_TYPE_P(zv) == IS_OBJECT && Z_REFCOUNT_P(zv) == 1) {
218
34.9k
    return ZEND_HASH_APPLY_REMOVE;
219
1.53M
  } else {
220
1.53M
    return ZEND_HASH_APPLY_KEEP;
221
1.53M
  }
222
1.56M
}
223
/* }}} */
224
225
static void zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */
226
199k
{
227
199k
  if (Z_TYPE_P(zv) == IS_INDIRECT) {
228
122k
    zv = Z_INDIRECT_P(zv);
229
122k
  }
230
199k
  i_zval_ptr_dtor(zv);
231
199k
}
232
/* }}} */
233
234
static ZEND_COLD void zend_throw_or_error(uint32_t fetch_type, zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
235
1.24k
{
236
1.24k
  va_list va;
237
1.24k
  char *message = NULL;
238
239
1.24k
  va_start(va, format);
240
1.24k
  zend_vspprintf(&message, 0, format, va);
241
242
1.24k
  if (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) {
243
1.24k
    zend_throw_error(exception_ce, "%s", message);
244
1.24k
  } else {
245
0
    zend_error_noreturn(E_ERROR, "%s", message);
246
0
  }
247
248
1.24k
  efree(message);
249
1.24k
  va_end(va);
250
1.24k
}
251
/* }}} */
252
253
void shutdown_destructors(void) /* {{{ */
254
247k
{
255
247k
  if (CG(unclean_shutdown)) {
256
18.5k
    EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
257
18.5k
  }
258
247k
  zend_try {
259
247k
    uint32_t symbols;
260
273k
    do {
261
273k
      symbols = zend_hash_num_elements(&EG(symbol_table));
262
273k
      zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor);
263
273k
    } while (symbols != zend_hash_num_elements(&EG(symbol_table)));
264
247k
    zend_objects_store_call_destructors(&EG(objects_store));
265
247k
  } zend_catch {
266
    /* if we couldn't destruct cleanly, mark all objects as destructed anyway */
267
0
    zend_objects_store_mark_destructed(&EG(objects_store));
268
0
  } zend_end_try();
269
247k
}
270
/* }}} */
271
272
/* Free values held by the executor. */
273
ZEND_API void zend_shutdown_executor_values(bool fast_shutdown)
274
247k
{
275
247k
  EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN;
276
247k
  zend_close_rsrc_list(&EG(regular_list));
277
278
  /* No PHP callback functions should be called after this point. */
279
247k
  EG(active) = 0;
280
281
247k
  if (!fast_shutdown) {
282
247k
    zval *zv;
283
284
247k
    zend_hash_graceful_reverse_destroy(&EG(symbol_table));
285
286
    /* Constants may contain objects, destroy them before the object store. */
287
247k
    if (EG(full_tables_cleanup)) {
288
0
      zend_hash_reverse_apply(EG(zend_constants), clean_non_persistent_constant_full);
289
247k
    } else {
290
247k
      zend_string *key;
291
996k
      ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(zend_constants), key, zv) {
292
996k
        zend_constant *c = Z_PTR_P(zv);
293
996k
        if (_idx == EG(persistent_constants_count)) {
294
247k
          break;
295
247k
        }
296
2.67k
        zval_ptr_dtor_nogc(&c->value);
297
2.67k
        if (c->name) {
298
2.67k
          zend_string_release_ex(c->name, 0);
299
2.67k
        }
300
2.67k
        if (c->filename) {
301
2.60k
          zend_string_release_ex(c->filename, 0);
302
2.60k
        }
303
2.67k
        if (c->attributes) {
304
196
          zend_hash_release(c->attributes);
305
196
        }
306
2.67k
        efree(c);
307
2.67k
        zend_string_release_ex(key, 0);
308
2.67k
      } ZEND_HASH_MAP_FOREACH_END_DEL();
309
247k
    }
310
311
247k
    zval_ptr_dtor(&EG(last_fatal_error_backtrace));
312
247k
    ZVAL_UNDEF(&EG(last_fatal_error_backtrace));
313
314
    /* Release static properties and static variables prior to the final GC run,
315
     * as they may hold GC roots. */
316
1.02M
    ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(function_table), zv) {
317
1.02M
      zend_op_array *op_array = Z_PTR_P(zv);
318
1.02M
      if (op_array->type == ZEND_INTERNAL_FUNCTION) {
319
247k
        break;
320
247k
      }
321
17.3k
      if (ZEND_MAP_PTR(op_array->static_variables_ptr)) {
322
297
        HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
323
297
        if (ht) {
324
274
          zend_array_destroy(ht);
325
274
          ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
326
274
        }
327
297
      }
328
17.3k
    } ZEND_HASH_FOREACH_END();
329
82.4M
    ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) {
330
82.4M
      zend_class_entry *ce = Z_PTR_P(zv);
331
332
82.4M
      if (ce->default_static_members_count) {
333
2.55k
        zend_cleanup_internal_class_data(ce);
334
2.55k
      }
335
336
82.4M
      if (ZEND_MAP_PTR(ce->mutable_data)) {
337
1.23M
        if (ZEND_MAP_PTR_GET_IMM(ce->mutable_data)) {
338
723
          zend_cleanup_mutable_class_data(ce);
339
723
        }
340
39.7M
      } else if (ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_IMMUTABLE)) {
341
        /* Constants may contain objects, destroy the values before the object store. */
342
61.3k
        zend_class_constant *c;
343
147k
        ZEND_HASH_MAP_FOREACH_PTR(&ce->constants_table, c) {
344
147k
          if (c->ce == ce) {
345
7.22k
            zval_ptr_dtor_nogc(&c->value);
346
7.22k
            ZVAL_UNDEF(&c->value);
347
7.22k
          }
348
147k
        } ZEND_HASH_FOREACH_END();
349
350
        /* properties may contain objects as well */
351
61.3k
        if (ce->default_properties_table) {
352
22.8k
          zval *p = ce->default_properties_table;
353
22.8k
          zval *end = p + ce->default_properties_count;
354
355
49.6k
          while (p != end) {
356
26.7k
            i_zval_ptr_dtor(p);
357
26.7k
            ZVAL_UNDEF(p);
358
26.7k
            p++;
359
26.7k
          }
360
22.8k
        }
361
61.3k
      }
362
363
82.4M
      if (ce->type == ZEND_USER_CLASS && ce->backed_enum_table) {
364
266
        ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_IMMUTABLE));
365
266
        zend_hash_release(ce->backed_enum_table);
366
266
        ce->backed_enum_table = NULL;
367
266
      }
368
369
40.9M
      if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
370
435
        zend_op_array *op_array;
371
1.94k
        ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) {
372
1.94k
          if (op_array->type == ZEND_USER_FUNCTION) {
373
535
            if (ZEND_MAP_PTR(op_array->static_variables_ptr)) {
374
225
              HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
375
225
              if (ht) {
376
135
                zend_array_destroy(ht);
377
135
                ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
378
135
              }
379
225
            }
380
535
          }
381
1.94k
        } ZEND_HASH_FOREACH_END();
382
383
435
        if (ce->num_hooked_props) {
384
47
          zend_property_info *prop_info;
385
238
          ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop_info) {
386
238
            if (prop_info->ce == ce) {
387
72
              if (prop_info->hooks) {
388
141
                for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
389
94
                  if (prop_info->hooks[i]) {
390
47
                    ZEND_ASSERT(ZEND_USER_CODE(prop_info->hooks[i]->type));
391
47
                    op_array = &prop_info->hooks[i]->op_array;
392
47
                    if (ZEND_MAP_PTR(op_array->static_variables_ptr)) {
393
18
                      HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
394
18
                      if (ht) {
395
13
                        zend_array_destroy(ht);
396
13
                        ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
397
13
                      }
398
18
                    }
399
47
                  }
400
94
                }
401
47
              }
402
72
            }
403
238
          } ZEND_HASH_FOREACH_END();
404
47
        }
405
435
      }
406
40.9M
    } ZEND_HASH_FOREACH_END();
407
408
    /* Also release error and exception handlers, which may hold objects. */
409
247k
    if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
410
0
      zval_ptr_dtor(&EG(user_error_handler));
411
0
      ZVAL_UNDEF(&EG(user_error_handler));
412
0
    }
413
414
247k
    if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
415
74
      zval_ptr_dtor(&EG(user_exception_handler));
416
74
      ZVAL_UNDEF(&EG(user_exception_handler));
417
74
    }
418
419
247k
    zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1);
420
247k
    zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
421
247k
    zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
422
423
247k
    zend_hash_clean(&EG(callable_convert_cache));
424
425
247k
#if ZEND_DEBUG
426
247k
    if (!CG(unclean_shutdown)) {
427
229k
      gc_collect_cycles();
428
229k
    }
429
247k
#endif
430
247k
  } else {
431
0
    zend_hash_discard(EG(zend_constants), EG(persistent_constants_count));
432
0
  }
433
434
247k
  zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown);
435
247k
}
436
437
void shutdown_executor(void) /* {{{ */
438
247k
{
439
247k
#if ZEND_DEBUG
440
247k
  bool fast_shutdown = 0;
441
#elif defined(__SANITIZE_ADDRESS__)
442
  char *force_fast_shutdown = getenv("ZEND_ASAN_FORCE_FAST_SHUTDOWN");
443
  bool fast_shutdown = (
444
    is_zend_mm()
445
    || (force_fast_shutdown && ZEND_ATOL(force_fast_shutdown))
446
  ) && !EG(full_tables_cleanup);
447
#else
448
  bool fast_shutdown = is_zend_mm() && !EG(full_tables_cleanup);
449
#endif
450
451
247k
  zend_try {
452
247k
    zend_stream_shutdown();
453
247k
  } zend_end_try();
454
455
247k
  zend_shutdown_executor_values(fast_shutdown);
456
457
247k
  zend_weakrefs_shutdown();
458
247k
  zend_max_execution_timer_shutdown();
459
247k
  zend_fiber_shutdown();
460
461
247k
  zend_try {
462
247k
    zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
463
247k
  } zend_end_try();
464
465
247k
  if (fast_shutdown) {
466
    /* Fast Request Shutdown
467
     * =====================
468
     * Zend Memory Manager frees memory by its own. We don't have to free
469
     * each allocated block separately.
470
     */
471
0
    zend_hash_discard(EG(function_table), EG(persistent_functions_count));
472
0
    zend_hash_discard(EG(class_table), EG(persistent_classes_count));
473
247k
  } else {
474
247k
    zend_vm_stack_destroy();
475
476
247k
    if (EG(full_tables_cleanup)) {
477
0
      zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function_full);
478
0
      zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class_full);
479
247k
    } else {
480
247k
      zend_string *key;
481
247k
      zval *zv;
482
1.02M
      ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(function_table), key, zv) {
483
1.02M
        zend_function *func = Z_PTR_P(zv);
484
1.02M
        if (_idx == EG(persistent_functions_count)) {
485
247k
          break;
486
247k
        }
487
17.3k
        destroy_op_array(&func->op_array);
488
17.3k
        zend_string_release_ex(key, 0);
489
17.3k
      } ZEND_HASH_MAP_FOREACH_END_DEL();
490
491
1.16M
      ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) {
492
1.16M
        if (_idx == EG(persistent_classes_count)) {
493
247k
          break;
494
247k
        }
495
88.5k
        destroy_zend_class(zv);
496
88.5k
        zend_string_release_ex(key, 0);
497
88.5k
      } ZEND_HASH_MAP_FOREACH_END_DEL();
498
247k
    }
499
500
248k
    while (EG(symtable_cache_ptr) > EG(symtable_cache)) {
501
1.03k
      EG(symtable_cache_ptr)--;
502
1.03k
      zend_hash_destroy(*EG(symtable_cache_ptr));
503
1.03k
      FREE_HASHTABLE(*EG(symtable_cache_ptr));
504
1.03k
    }
505
506
247k
    zend_hash_destroy(&EG(included_files));
507
508
247k
    zend_stack_destroy(&EG(user_error_handlers_error_reporting));
509
247k
    zend_stack_destroy(&EG(user_error_handlers));
510
247k
    zend_stack_destroy(&EG(user_exception_handlers));
511
247k
    zend_lazy_objects_destroy(&EG(lazy_objects_store));
512
247k
    zend_objects_store_destroy(&EG(objects_store));
513
247k
    if (EG(in_autoload)) {
514
5.15k
      zend_hash_destroy(EG(in_autoload));
515
5.15k
      FREE_HASHTABLE(EG(in_autoload));
516
5.15k
    }
517
518
247k
    if (EG(ht_iterators) != EG(ht_iterators_slots)) {
519
6
      efree(EG(ht_iterators));
520
6
    }
521
522
247k
    zend_hash_destroy(&EG(callable_convert_cache));
523
247k
  }
524
525
247k
#if ZEND_DEBUG
526
247k
  if (EG(ht_iterators_used) && !CG(unclean_shutdown)) {
527
0
    zend_error(E_WARNING, "Leaked %" PRIu32 " hashtable iterators", EG(ht_iterators_used));
528
0
  }
529
247k
#endif
530
531
  /* Check whether anyone is hogging the trampoline. */
532
247k
  ZEND_ASSERT(EG(trampoline).common.function_name == NULL || CG(unclean_shutdown));
533
534
247k
  EG(ht_iterators_used) = 0;
535
536
247k
  zend_shutdown_fpu();
537
247k
}
538
/* }}} */
539
540
/* return class name and "::" or "". */
541
ZEND_API const char *get_active_class_name(const char **space) /* {{{ */
542
10
{
543
10
  const zend_function *func;
544
545
10
  if (!zend_is_executing()) {
546
0
    if (space) {
547
0
      *space = "";
548
0
    }
549
0
    return "";
550
0
  }
551
552
10
  func = zend_active_function();
553
554
10
  switch (func->type) {
555
0
    case ZEND_USER_FUNCTION:
556
10
    case ZEND_INTERNAL_FUNCTION:
557
10
    {
558
10
      const zend_class_entry *ce = func->common.scope;
559
560
10
      if (space) {
561
10
        *space = ce ? "::" : "";
562
10
      }
563
10
      return ce ? ZSTR_VAL(ce->name) : "";
564
0
    }
565
0
    default:
566
0
      if (space) {
567
0
        *space = "";
568
0
      }
569
0
      return "";
570
10
  }
571
10
}
572
/* }}} */
573
574
ZEND_API const char *get_active_function_name(void) /* {{{ */
575
59
{
576
59
  const zend_function *func;
577
578
59
  if (!zend_is_executing()) {
579
0
    return NULL;
580
0
  }
581
582
59
  func = zend_active_function();
583
584
59
  switch (func->type) {
585
0
    case ZEND_USER_FUNCTION: {
586
0
        const zend_string *function_name = func->common.function_name;
587
588
0
        if (function_name) {
589
0
          return ZSTR_VAL(function_name);
590
0
        } else {
591
0
          return "main";
592
0
        }
593
0
      }
594
0
      break;
595
59
    case ZEND_INTERNAL_FUNCTION:
596
59
      return ZSTR_VAL(func->common.function_name);
597
0
      break;
598
0
    default:
599
0
      return NULL;
600
59
  }
601
59
}
602
/* }}} */
603
604
ZEND_API const zend_function *zend_active_function_ex(const zend_execute_data *execute_data)
605
1.39k
{
606
1.39k
  const zend_function *func = EX(func);
607
608
  /* Resolve function if op is a frameless call. */
609
1.39k
  if (ZEND_USER_CODE(func->type)) {
610
1.39k
    const zend_op *op = EX(opline);
611
1.39k
    if (ZEND_OP_IS_FRAMELESS_ICALL(op->opcode)) {
612
0
      func = ZEND_FLF_FUNC(op);
613
0
    }
614
1.39k
  }
615
616
1.39k
  return func;
617
1.39k
}
618
619
ZEND_API zend_string *get_active_function_or_method_name(void) /* {{{ */
620
6.19k
{
621
6.19k
  ZEND_ASSERT(zend_is_executing());
622
623
6.19k
  return get_function_or_method_name(zend_active_function());
624
6.19k
}
625
/* }}} */
626
627
ZEND_API zend_string *get_function_or_method_name(const zend_function *func) /* {{{ */
628
9.57k
{
629
9.57k
  if (func->common.scope && func->common.function_name) {
630
3.74k
    return zend_create_member_string(func->common.scope->name, func->common.function_name);
631
3.74k
  }
632
633
5.83k
  return func->common.function_name ? zend_string_copy(func->common.function_name) : ZSTR_INIT_LITERAL("main", 0);
634
9.57k
}
635
/* }}} */
636
637
ZEND_API const char *get_active_function_arg_name(uint32_t arg_num) /* {{{ */
638
5.61k
{
639
5.61k
  if (!zend_is_executing()) {
640
0
    return NULL;
641
0
  }
642
643
5.61k
  const zend_function *func = zend_active_function();
644
645
5.61k
  return get_function_arg_name(func, arg_num);
646
5.61k
}
647
/* }}} */
648
649
ZEND_API const char *get_function_arg_name(const zend_function *func, uint32_t arg_num) /* {{{ */
650
6.05k
{
651
6.05k
  if (!func || arg_num == 0 || func->common.num_args < arg_num) {
652
48
    return NULL;
653
48
  }
654
655
6.00k
  if (func->type == ZEND_USER_FUNCTION || (func->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
656
1.01k
    return ZSTR_VAL(func->common.arg_info[arg_num - 1].name);
657
4.98k
  } else {
658
4.98k
    return ((zend_internal_arg_info*) func->common.arg_info)[arg_num - 1].name;
659
4.98k
  }
660
6.00k
}
661
/* }}} */
662
663
ZEND_API const char *zend_get_executed_filename(void) /* {{{ */
664
776k
{
665
776k
  const zend_string *filename = zend_get_executed_filename_ex();
666
776k
  return filename != NULL ? ZSTR_VAL(filename) : "[no active file]";
667
776k
}
668
/* }}} */
669
670
ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */
671
3.01M
{
672
3.01M
  zend_string *filename_override = EG(filename_override);
673
3.01M
  if (filename_override != NULL) {
674
199
    return filename_override;
675
199
  }
676
677
3.01M
  const zend_execute_data *ex = EG(current_execute_data);
678
679
4.55M
  while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
680
1.53M
    ex = ex->prev_execute_data;
681
1.53M
  }
682
3.01M
  if (ex) {
683
1.85M
    return ex->func->op_array.filename;
684
1.85M
  } else {
685
1.16M
    return NULL;
686
1.16M
  }
687
3.01M
}
688
/* }}} */
689
690
ZEND_API uint32_t zend_get_executed_lineno(void) /* {{{ */
691
2.95M
{
692
2.95M
  zend_long lineno_override = EG(lineno_override);
693
2.95M
  if (lineno_override != -1) {
694
199
    return lineno_override;
695
199
  }
696
697
2.94M
  const zend_execute_data *ex = EG(current_execute_data);
698
699
4.48M
  while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
700
1.53M
    ex = ex->prev_execute_data;
701
1.53M
  }
702
2.94M
  if (ex) {
703
1.78M
    if (!ex->opline) {
704
      /* Missing SAVE_OPLINE()? Falling back to first line of function */
705
0
      return ex->func->op_array.opcodes[0].lineno;
706
0
    }
707
1.78M
    if (EG(exception) && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
708
50
        ex->opline->lineno == 0 && EG(opline_before_exception)) {
709
50
      return EG(opline_before_exception)->lineno;
710
50
    }
711
1.78M
    return ex->opline->lineno;
712
1.78M
  } else {
713
1.16M
    return 0;
714
1.16M
  }
715
2.94M
}
716
/* }}} */
717
718
ZEND_API zend_class_entry *zend_get_executed_scope(void) /* {{{ */
719
11.0k
{
720
11.0k
  const zend_execute_data *ex = EG(current_execute_data);
721
722
12.2k
  while (1) {
723
12.2k
    if (!ex) {
724
20
      return NULL;
725
12.2k
    } else if (ex->func && (ZEND_USER_CODE(ex->func->type) || ex->func->common.scope)) {
726
11.0k
      return ex->func->common.scope;
727
11.0k
    }
728
1.21k
    ex = ex->prev_execute_data;
729
1.21k
  }
730
11.0k
}
731
/* }}} */
732
733
ZEND_API bool zend_is_executing(void) /* {{{ */
734
2.52M
{
735
2.52M
  return EG(current_execute_data) != 0;
736
2.52M
}
737
/* }}} */
738
739
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_with_ctx(zval *p, zend_class_entry *scope, zend_ast_evaluate_ctx *ctx)
740
5.16k
{
741
5.16k
  if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
742
5.16k
    zend_ast *ast = Z_ASTVAL_P(p);
743
744
5.16k
    if (ast->kind == ZEND_AST_CONSTANT) {
745
556
      zend_string *name = zend_ast_get_constant_name(ast);
746
556
      const zval *zv = zend_get_constant_ex(name, scope, ast->attr);
747
556
      if (UNEXPECTED(zv == NULL)) {
748
87
        return FAILURE;
749
87
      }
750
751
469
      zval_ptr_dtor_nogc(p);
752
469
      ZVAL_COPY_OR_DUP(p, zv);
753
4.61k
    } else {
754
4.61k
      zval tmp;
755
4.61k
      bool short_circuited;
756
757
      // Increase the refcount during zend_ast_evaluate to avoid releasing the ast too early
758
      // on nested calls to zval_update_constant_ex which can happen when retriggering ast
759
      // evaluation during autoloading.
760
4.61k
      zend_ast_ref *ast_ref = Z_AST_P(p);
761
4.61k
      bool ast_is_refcounted = !(GC_FLAGS(ast_ref) & GC_IMMUTABLE);
762
4.61k
      if (ast_is_refcounted) {
763
285
        GC_ADDREF(ast_ref);
764
285
      }
765
4.61k
      zend_result result = zend_ast_evaluate_ex(&tmp, ast, scope, &short_circuited, ctx) != SUCCESS;
766
4.61k
      if (ast_is_refcounted && !GC_DELREF(ast_ref)) {
767
6
        rc_dtor_func((zend_refcounted *)ast_ref);
768
6
      }
769
4.61k
      if (UNEXPECTED(result != SUCCESS)) {
770
547
        return FAILURE;
771
547
      }
772
4.06k
      zval_ptr_dtor_nogc(p);
773
4.06k
      ZVAL_COPY_VALUE(p, &tmp);
774
4.06k
    }
775
5.16k
  }
776
4.53k
  return SUCCESS;
777
5.16k
}
778
/* }}} */
779
780
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_ex(zval *p, zend_class_entry *scope)
781
4.60k
{
782
4.60k
  zend_ast_evaluate_ctx ctx = {0};
783
4.60k
  return zval_update_constant_with_ctx(p, scope, &ctx);
784
4.60k
}
785
786
ZEND_API zend_result ZEND_FASTCALL zval_update_constant(zval *pp) /* {{{ */
787
0
{
788
0
  return zval_update_constant_ex(pp, EG(current_execute_data) ? zend_get_executed_scope() : CG(active_class_entry));
789
0
}
790
/* }}} */
791
792
zend_result _call_user_function_impl(zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], HashTable *named_params) /* {{{ */
793
53
{
794
53
  zend_fcall_info fci;
795
796
53
  fci.size = sizeof(fci);
797
53
  if (object) {
798
27
    ZEND_ASSERT(Z_TYPE_P(object) == IS_OBJECT);
799
27
    fci.object = Z_OBJ_P(object);
800
27
  } else {
801
26
    fci.object = NULL;
802
26
  }
803
53
  ZVAL_COPY_VALUE(&fci.function_name, function_name);
804
53
  fci.retval = retval_ptr;
805
53
  fci.param_count = param_count;
806
53
  fci.params = params;
807
53
  fci.named_params = named_params;
808
809
53
  return zend_call_function(&fci, NULL);
810
53
}
811
/* }}} */
812
813
zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /* {{{ */
814
557k
{
815
557k
  zend_execute_data *call;
816
557k
  zend_fcall_info_cache fci_cache_local;
817
557k
  zend_function *func;
818
557k
  uint32_t call_info;
819
557k
  void *object_or_called_scope;
820
821
557k
  ZVAL_UNDEF(fci->retval);
822
823
557k
  if (!EG(active)) {
824
0
    return FAILURE; /* executor is already inactive */
825
0
  }
826
827
557k
  if (EG(exception)) {
828
684
    if (fci_cache) {
829
684
      zend_release_fcall_info_cache(fci_cache);
830
684
    }
831
684
    return SUCCESS; /* we would result in an unstable executor otherwise */
832
684
  }
833
834
556k
  ZEND_ASSERT(ZEND_FCI_INITIALIZED(*fci));
835
836
556k
  if (!fci_cache || !fci_cache->function_handler) {
837
81
    char *error = NULL;
838
839
81
    if (!fci_cache) {
840
53
      fci_cache = &fci_cache_local;
841
53
    }
842
843
81
    if (!zend_is_callable_ex(&fci->function_name, fci->object, 0, NULL, fci_cache, &error)) {
844
14
      ZEND_ASSERT(error && "Should have error if not callable");
845
14
      zend_string *callable_name
846
14
        = zend_get_callable_name_ex(&fci->function_name, fci->object);
847
14
      zend_throw_error(NULL, "Invalid callback %s, %s", ZSTR_VAL(callable_name), error);
848
14
      efree(error);
849
14
      zend_string_release_ex(callable_name, 0);
850
14
      return SUCCESS;
851
14
    }
852
853
67
    ZEND_ASSERT(!error);
854
67
  }
855
856
556k
  func = fci_cache->function_handler;
857
556k
  if ((func->common.fn_flags & ZEND_ACC_STATIC) || !fci_cache->object) {
858
87.7k
    object_or_called_scope = fci_cache->called_scope;
859
87.7k
    call_info = ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC;
860
469k
  } else {
861
469k
    object_or_called_scope = fci_cache->object;
862
469k
    call_info = ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC | ZEND_CALL_HAS_THIS;
863
469k
  }
864
865
556k
  if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_DEPRECATED)) {
866
17
    zend_deprecated_function(func);
867
868
17
    if (UNEXPECTED(EG(exception))) {
869
0
      return SUCCESS;
870
0
    }
871
17
  }
872
873
556k
  call = zend_vm_stack_push_call_frame(call_info,
874
556k
    func, fci->param_count, object_or_called_scope);
875
876
1.11M
  for (uint32_t i = 0; i < fci->param_count; i++) {
877
553k
    zval *param = ZEND_CALL_ARG(call, i+1);
878
553k
    zval *arg = &fci->params[i];
879
553k
    bool must_wrap = false;
880
553k
    if (UNEXPECTED(Z_ISUNDEF_P(arg))) {
881
      /* Allow forwarding undef slots. This is only used by Closure::__invoke(). */
882
14
      ZVAL_UNDEF(param);
883
14
      ZEND_ADD_CALL_FLAG(call, ZEND_CALL_MAY_HAVE_UNDEF);
884
14
      continue;
885
14
    }
886
887
553k
    if (ARG_SHOULD_BE_SENT_BY_REF(func, i + 1)) {
888
316
      if (UNEXPECTED(!Z_ISREF_P(arg))) {
889
86
        if (!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
890
          /* By-value send is not allowed -- emit a warning,
891
           * and perform the call with the value wrapped in a reference. */
892
68
          zend_param_must_be_ref(func, i + 1);
893
68
          must_wrap = true;
894
68
          if (UNEXPECTED(EG(exception))) {
895
0
            ZEND_CALL_NUM_ARGS(call) = i;
896
27
cleanup_args:
897
27
            zend_vm_stack_free_args(call);
898
27
            if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
899
5
              zend_free_extra_named_params(call->extra_named_params);
900
5
            }
901
27
            zend_vm_stack_free_call_frame(call);
902
27
            zend_release_fcall_info_cache(fci_cache);
903
27
            return SUCCESS;
904
0
          }
905
68
        }
906
86
      }
907
552k
    } else {
908
552k
      if (Z_ISREF_P(arg) &&
909
710
          !(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
910
        /* don't separate references for __call */
911
710
        arg = Z_REFVAL_P(arg);
912
710
      }
913
552k
    }
914
915
553k
    if (EXPECTED(!must_wrap)) {
916
553k
      ZVAL_COPY(param, arg);
917
553k
    } else {
918
68
      Z_TRY_ADDREF_P(arg);
919
68
      ZVAL_NEW_REF(param, arg);
920
68
    }
921
553k
  }
922
923
556k
  if (fci->named_params) {
924
685
    zend_string *name;
925
685
    zval *arg;
926
685
    uint32_t arg_num = ZEND_CALL_NUM_ARGS(call) + 1;
927
685
    bool have_named_params = false;
928
2.73k
    ZEND_HASH_FOREACH_STR_KEY_VAL(fci->named_params, name, arg) {
929
2.73k
      bool must_wrap = false;
930
2.73k
      zval *target;
931
2.73k
      if (name) {
932
782
        void *cache_slot[2] = {NULL, NULL};
933
782
        have_named_params = true;
934
782
        target = zend_handle_named_arg(&call, name, &arg_num, cache_slot);
935
782
        if (!target) {
936
17
          goto cleanup_args;
937
17
        }
938
782
      } else {
939
243
        if (have_named_params) {
940
10
          zend_throw_error(NULL,
941
10
            "Cannot use positional argument after named argument");
942
10
          goto cleanup_args;
943
10
        }
944
945
233
        zend_vm_stack_extend_call_frame(&call, arg_num - 1, 1);
946
233
        target = ZEND_CALL_ARG(call, arg_num);
947
233
      }
948
949
998
      if (ARG_SHOULD_BE_SENT_BY_REF(func, arg_num)) {
950
56
        if (UNEXPECTED(!Z_ISREF_P(arg))) {
951
55
          if (!ARG_MAY_BE_SENT_BY_REF(func, arg_num)) {
952
            /* By-value send is not allowed -- emit a warning,
953
             * and perform the call with the value wrapped in a reference. */
954
45
            zend_param_must_be_ref(func, arg_num);
955
45
            must_wrap = true;
956
45
            if (UNEXPECTED(EG(exception))) {
957
0
              goto cleanup_args;
958
0
            }
959
45
          }
960
55
        }
961
942
      } else {
962
942
        if (Z_ISREF_P(arg) &&
963
0
          !(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
964
          /* don't separate references for __call */
965
0
          arg = Z_REFVAL_P(arg);
966
0
        }
967
942
      }
968
969
998
      if (EXPECTED(!must_wrap)) {
970
953
        ZVAL_COPY(target, arg);
971
953
      } else {
972
45
        Z_TRY_ADDREF_P(arg);
973
45
        ZVAL_NEW_REF(target, arg);
974
45
      }
975
998
      if (!name) {
976
233
        ZEND_CALL_NUM_ARGS(call)++;
977
233
        arg_num++;
978
233
      }
979
998
    } ZEND_HASH_FOREACH_END();
980
685
  }
981
982
556k
  if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_MAY_HAVE_UNDEF)) {
983
    /* zend_handle_undef_args assumes prev_execute_data is initialized. */
984
454
    call->prev_execute_data = NULL;
985
454
    if (zend_handle_undef_args(call) == FAILURE) {
986
30
      zend_vm_stack_free_args(call);
987
30
      zend_vm_stack_free_call_frame(call);
988
30
      return SUCCESS;
989
30
    }
990
454
  }
991
992
556k
  if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
993
6.71k
    uint32_t call_info;
994
995
6.71k
    GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
996
6.71k
    call_info = ZEND_CALL_CLOSURE;
997
6.71k
    if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
998
88
      call_info |= ZEND_CALL_FAKE_CLOSURE;
999
88
    }
1000
6.71k
    ZEND_ADD_CALL_FLAG(call, call_info);
1001
6.71k
  }
1002
1003
556k
  if (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
1004
1.38k
    fci_cache->function_handler = NULL;
1005
1.38k
  }
1006
1007
556k
  const zend_class_entry *orig_fake_scope = EG(fake_scope);
1008
556k
  EG(fake_scope) = NULL;
1009
556k
  if (func->type == ZEND_USER_FUNCTION) {
1010
89.3k
    uint32_t orig_jit_trace_num = EG(jit_trace_num);
1011
1012
89.3k
    zend_init_func_execute_data(call, &func->op_array, fci->retval);
1013
89.3k
    ZEND_OBSERVER_FCALL_BEGIN(call);
1014
89.3k
    zend_execute_ex(call);
1015
89.3k
    EG(jit_trace_num) = orig_jit_trace_num;
1016
467k
  } else {
1017
467k
    ZEND_ASSERT(func->type == ZEND_INTERNAL_FUNCTION);
1018
467k
    ZVAL_NULL(fci->retval);
1019
467k
    call->prev_execute_data = EG(current_execute_data);
1020
467k
    EG(current_execute_data) = call;
1021
467k
#if ZEND_DEBUG
1022
467k
    bool should_throw = zend_internal_call_should_throw(func, call);
1023
467k
#endif
1024
467k
    ZEND_OBSERVER_FCALL_BEGIN(call);
1025
467k
    if (EXPECTED(zend_execute_internal == NULL)) {
1026
      /* saves one function call if zend_execute_internal is not used */
1027
383k
      func->internal_function.handler(call, fci->retval);
1028
383k
    } else {
1029
84.3k
      zend_execute_internal(call, fci->retval);
1030
84.3k
    }
1031
1032
467k
#if ZEND_DEBUG
1033
467k
    if (!EG(exception) && call->func) {
1034
403k
      if (should_throw) {
1035
0
        zend_internal_call_arginfo_violation(call->func);
1036
0
      }
1037
403k
      ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
1038
403k
        zend_verify_internal_return_type(call->func, fci->retval));
1039
403k
      ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
1040
403k
        ? Z_ISREF_P(fci->retval) : !Z_ISREF_P(fci->retval));
1041
403k
    }
1042
467k
#endif
1043
467k
    ZEND_OBSERVER_FCALL_END(call, fci->retval);
1044
467k
    EG(current_execute_data) = call->prev_execute_data;
1045
467k
    zend_vm_stack_free_args(call);
1046
467k
    if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
1047
17
      zend_array_release(call->extra_named_params);
1048
17
    }
1049
1050
467k
    if (EG(exception)) {
1051
62.1k
      zval_ptr_dtor(fci->retval);
1052
62.1k
      ZVAL_UNDEF(fci->retval);
1053
62.1k
    }
1054
1055
    /* This flag is regularly checked while running user functions, but not internal
1056
     * So see whether interrupt flag was set while the function was running... */
1057
467k
    if (zend_atomic_bool_exchange_ex(&EG(vm_interrupt), false)) {
1058
0
      if (zend_atomic_bool_load_ex(&EG(timed_out))) {
1059
0
        zend_timeout();
1060
0
      } else if (zend_interrupt_function) {
1061
0
        zend_interrupt_function(EG(current_execute_data));
1062
0
      }
1063
0
    }
1064
1065
467k
    if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) {
1066
35
      OBJ_RELEASE(Z_OBJ(call->This));
1067
35
    }
1068
467k
  }
1069
556k
  EG(fake_scope) = orig_fake_scope;
1070
1071
556k
  zend_vm_stack_free_call_frame(call);
1072
1073
556k
  if (UNEXPECTED(EG(exception))) {
1074
65.9k
    if (UNEXPECTED(!EG(current_execute_data))) {
1075
845
      zend_throw_exception_internal(NULL);
1076
65.0k
    } else if (EG(current_execute_data)->func &&
1077
65.0k
               ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
1078
1.87k
      zend_rethrow_exception(EG(current_execute_data));
1079
1.87k
    }
1080
65.9k
  }
1081
1082
556k
  return SUCCESS;
1083
556k
}
1084
/* }}} */
1085
1086
ZEND_API void zend_call_known_function(
1087
    zend_function *fn, zend_object *object, zend_class_entry *called_scope, zval *retval_ptr,
1088
    uint32_t param_count, zval *params, HashTable *named_params)
1089
545k
{
1090
545k
  zval retval;
1091
545k
  zend_fcall_info fci;
1092
545k
  zend_fcall_info_cache fcic;
1093
1094
545k
  ZEND_ASSERT(fn && "zend_function must be passed!");
1095
1096
545k
  fci.size = sizeof(fci);
1097
545k
  fci.object = object;
1098
545k
  fci.retval = retval_ptr ? retval_ptr : &retval;
1099
545k
  fci.param_count = param_count;
1100
545k
  fci.params = params;
1101
545k
  fci.named_params = named_params;
1102
545k
  ZVAL_UNDEF(&fci.function_name); /* Unused */
1103
1104
545k
  fcic.function_handler = fn;
1105
545k
  fcic.object = object;
1106
545k
  fcic.called_scope = called_scope;
1107
1108
545k
  zend_result result = zend_call_function(&fci, &fcic);
1109
545k
  if (UNEXPECTED(result == FAILURE)) {
1110
0
    if (!EG(exception)) {
1111
0
      zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s",
1112
0
        fn->common.scope ? ZSTR_VAL(fn->common.scope->name) : "",
1113
0
        fn->common.scope ? "::" : "", ZSTR_VAL(fn->common.function_name));
1114
0
    }
1115
0
  }
1116
1117
545k
  if (!retval_ptr) {
1118
380k
    zval_ptr_dtor(&retval);
1119
380k
  }
1120
545k
}
1121
1122
ZEND_API void zend_call_known_instance_method_with_2_params(
1123
    zend_function *fn, zend_object *object, zval *retval_ptr, zval *param1, zval *param2)
1124
301
{
1125
301
  zval params[2];
1126
301
  ZVAL_COPY_VALUE(&params[0], param1);
1127
301
  ZVAL_COPY_VALUE(&params[1], param2);
1128
301
  zend_call_known_instance_method(fn, object, retval_ptr, 2, params);
1129
301
}
1130
1131
ZEND_API zend_result zend_call_method_if_exists(
1132
    zend_object *object, zend_string *method_name, zval *retval,
1133
    uint32_t param_count, zval *params)
1134
6.61k
{
1135
6.61k
  zval zval_method;
1136
6.61k
  zend_fcall_info_cache fcc;
1137
1138
6.61k
  ZVAL_STR(&zval_method, method_name);
1139
1140
6.61k
  if (UNEXPECTED(!zend_is_callable_ex(&zval_method, object, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fcc, NULL))) {
1141
170
    ZVAL_UNDEF(retval);
1142
170
    return FAILURE;
1143
170
  }
1144
1145
6.44k
  zend_call_known_fcc(&fcc, retval, param_count, params, NULL);
1146
  /* Need to free potential trampoline (__call/__callStatic) copied function handler before releasing the closure */
1147
6.44k
  zend_release_fcall_info_cache(&fcc);
1148
6.44k
  return SUCCESS;
1149
6.61k
}
1150
1151
/* 0-9 a-z A-Z _ \ 0x80-0xff */
1152
static const uint32_t valid_chars[8] = {
1153
  0x00000000,
1154
  0x03ff0000,
1155
  0x97fffffe,
1156
  0x07fffffe,
1157
  0xffffffff,
1158
  0xffffffff,
1159
  0xffffffff,
1160
  0xffffffff,
1161
};
1162
1163
137k
ZEND_API bool zend_is_valid_class_name(const zend_string *name) {
1164
1.38M
  for (size_t i = 0; i < ZSTR_LEN(name); i++) {
1165
1.24M
    unsigned char c = ZSTR_VAL(name)[i];
1166
1.24M
    if (!ZEND_BIT_TEST(valid_chars, c)) {
1167
3.92k
      return 0;
1168
3.92k
    }
1169
1.24M
  }
1170
133k
  return 1;
1171
137k
}
1172
1173
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *key, uint32_t flags) /* {{{ */
1174
693k
{
1175
693k
  zend_class_entry *ce = NULL;
1176
693k
  zval *zv;
1177
693k
  zend_string *lc_name;
1178
693k
  zend_string *autoload_name;
1179
693k
  uint32_t ce_cache = 0;
1180
1181
693k
  if (ZSTR_HAS_CE_CACHE(name) && ZSTR_VALID_CE_CACHE(name)) {
1182
262k
    ce_cache = GC_REFCOUNT(name);
1183
262k
    ce = GET_CE_CACHE(ce_cache);
1184
262k
    if (EXPECTED(ce)) {
1185
194k
      return ce;
1186
194k
    }
1187
262k
  }
1188
1189
499k
  if (key) {
1190
277k
    lc_name = key;
1191
277k
  } else {
1192
221k
    if (!ZSTR_LEN(name)) {
1193
83
      return NULL;
1194
83
    }
1195
1196
221k
    if (ZSTR_VAL(name)[0] == '\\') {
1197
113
      lc_name = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
1198
113
      zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
1199
221k
    } else {
1200
221k
      lc_name = zend_string_tolower(name);
1201
221k
    }
1202
221k
  }
1203
1204
498k
  zv = zend_hash_find(EG(class_table), lc_name);
1205
498k
  if (zv) {
1206
90.3k
    if (!key) {
1207
28.7k
      zend_string_release_ex(lc_name, 0);
1208
28.7k
    }
1209
90.3k
    ce = (zend_class_entry*)Z_PTR_P(zv);
1210
90.3k
    if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_LINKED))) {
1211
3.96k
      if ((flags & ZEND_FETCH_CLASS_ALLOW_UNLINKED) ||
1212
81
        ((flags & ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED) &&
1213
3.92k
          (ce->ce_flags & ZEND_ACC_NEARLY_LINKED))) {
1214
3.92k
        if (!CG(unlinked_uses)) {
1215
218
          ALLOC_HASHTABLE(CG(unlinked_uses));
1216
218
          zend_hash_init(CG(unlinked_uses), 0, NULL, NULL, 0);
1217
218
        }
1218
3.92k
        zend_hash_index_add_empty_element(CG(unlinked_uses), (zend_long)(uintptr_t)ce);
1219
3.92k
        return ce;
1220
3.92k
      }
1221
40
      return NULL;
1222
3.96k
    }
1223
    /* Don't populate CE_CACHE for mutable classes during compilation.
1224
     * The class may be freed while persisting. */
1225
86.3k
    if (ce_cache &&
1226
60.7k
        (!CG(in_compilation) || (ce->ce_flags & ZEND_ACC_IMMUTABLE))) {
1227
57.0k
      SET_CE_CACHE(ce_cache, ce);
1228
57.0k
    }
1229
86.3k
    return ce;
1230
90.3k
  }
1231
1232
  /* The compiler is not-reentrant. Make sure we autoload only during run-time. */
1233
408k
  if ((flags & ZEND_FETCH_CLASS_NO_AUTOLOAD) || zend_is_compiling()) {
1234
268k
    if (!key) {
1235
187k
      zend_string_release_ex(lc_name, 0);
1236
187k
    }
1237
268k
    return NULL;
1238
268k
  }
1239
1240
139k
  if (!zend_autoload) {
1241
0
    if (!key) {
1242
0
      zend_string_release_ex(lc_name, 0);
1243
0
    }
1244
0
    return NULL;
1245
0
  }
1246
1247
  /* Verify class name before passing it to the autoloader. */
1248
139k
  if (!key && !ZSTR_HAS_CE_CACHE(name) && !zend_is_valid_class_name(name)) {
1249
3.81k
    zend_string_release_ex(lc_name, 0);
1250
3.81k
    return NULL;
1251
3.81k
  }
1252
1253
136k
  if (EG(in_autoload) == NULL) {
1254
5.15k
    ALLOC_HASHTABLE(EG(in_autoload));
1255
5.15k
    zend_hash_init(EG(in_autoload), 8, NULL, NULL, 0);
1256
5.15k
  }
1257
1258
136k
  if (zend_hash_add_empty_element(EG(in_autoload), lc_name) == NULL) {
1259
16
    if (!key) {
1260
7
      zend_string_release_ex(lc_name, 0);
1261
7
    }
1262
16
    return NULL;
1263
16
  }
1264
1265
136k
  if (ZSTR_VAL(name)[0] == '\\') {
1266
66
    autoload_name = zend_string_init(ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1, 0);
1267
136k
  } else {
1268
136k
    autoload_name = zend_string_copy(name);
1269
136k
  }
1270
1271
136k
  zend_string *previous_filename = EG(filename_override);
1272
136k
  zend_long previous_lineno = EG(lineno_override);
1273
136k
  EG(filename_override) = NULL;
1274
136k
  EG(lineno_override) = -1;
1275
136k
  zend_exception_save();
1276
136k
  ce = zend_autoload(autoload_name, lc_name);
1277
136k
  zend_exception_restore();
1278
136k
  EG(filename_override) = previous_filename;
1279
136k
  EG(lineno_override) = previous_lineno;
1280
1281
136k
  zend_string_release_ex(autoload_name, 0);
1282
136k
  zend_hash_del(EG(in_autoload), lc_name);
1283
1284
136k
  if (!key) {
1285
1.34k
    zend_string_release_ex(lc_name, 0);
1286
1.34k
  }
1287
136k
  if (ce) {
1288
479
    ZEND_ASSERT(!CG(in_compilation));
1289
479
    if (ce_cache) {
1290
374
      SET_CE_CACHE(ce_cache, ce);
1291
374
    }
1292
479
  }
1293
136k
  return ce;
1294
136k
}
1295
/* }}} */
1296
1297
ZEND_API zend_class_entry *zend_lookup_class(zend_string *name) /* {{{ */
1298
13.3k
{
1299
13.3k
  return zend_lookup_class_ex(name, NULL, 0);
1300
13.3k
}
1301
/* }}} */
1302
1303
ZEND_API zend_class_entry *zend_get_called_scope(const zend_execute_data *ex) /* {{{ */
1304
102k
{
1305
102k
  while (ex) {
1306
2.84k
    if (Z_TYPE(ex->This) == IS_OBJECT) {
1307
1.47k
      return Z_OBJCE(ex->This);
1308
1.47k
    } else if (Z_CE(ex->This)) {
1309
901
      return Z_CE(ex->This);
1310
901
    } else if (ex->func) {
1311
472
      if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
1312
432
        return NULL;
1313
432
      }
1314
472
    }
1315
40
    ex = ex->prev_execute_data;
1316
40
  }
1317
99.3k
  return NULL;
1318
102k
}
1319
/* }}} */
1320
1321
ZEND_API zend_object *zend_get_this_object(const zend_execute_data *ex) /* {{{ */
1322
101k
{
1323
101k
  while (ex) {
1324
2.61k
    if (Z_TYPE(ex->This) == IS_OBJECT) {
1325
2.00k
      return Z_OBJ(ex->This);
1326
2.00k
    } else if (ex->func) {
1327
609
      if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
1328
597
        return NULL;
1329
597
      }
1330
609
    }
1331
12
    ex = ex->prev_execute_data;
1332
12
  }
1333
99.3k
  return NULL;
1334
101k
}
1335
/* }}} */
1336
1337
ZEND_API zend_result zend_eval_stringl(const char *str, size_t str_len, zval *retval_ptr, const char *string_name) /* {{{ */
1338
0
{
1339
0
  zend_op_array *new_op_array;
1340
0
  uint32_t original_compiler_options;
1341
0
  zend_result retval;
1342
0
  zend_string *code_str;
1343
1344
0
  if (retval_ptr) {
1345
0
    code_str = zend_string_concat3(
1346
0
      "return ", sizeof("return ")-1, str, str_len, ";", sizeof(";")-1);
1347
0
  } else {
1348
0
    code_str = zend_string_init(str, str_len, 0);
1349
0
  }
1350
1351
  /*printf("Evaluating '%s'\n", pv.value.str.val);*/
1352
1353
0
  original_compiler_options = CG(compiler_options);
1354
0
  CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
1355
0
  new_op_array = zend_compile_string(code_str, string_name, ZEND_COMPILE_POSITION_AFTER_OPEN_TAG);
1356
0
  CG(compiler_options) = original_compiler_options;
1357
1358
0
  if (new_op_array) {
1359
0
    zval local_retval;
1360
1361
0
    EG(no_extensions)=1;
1362
1363
0
    new_op_array->scope = zend_get_executed_scope();
1364
1365
0
    zend_try {
1366
0
      ZVAL_UNDEF(&local_retval);
1367
0
      zend_execute(new_op_array, &local_retval);
1368
0
    } zend_catch {
1369
0
      destroy_op_array(new_op_array);
1370
0
      efree_size(new_op_array, sizeof(zend_op_array));
1371
0
      zend_bailout();
1372
0
    } zend_end_try();
1373
1374
0
    if (Z_TYPE(local_retval) != IS_UNDEF) {
1375
0
      if (retval_ptr) {
1376
0
        ZVAL_COPY_VALUE(retval_ptr, &local_retval);
1377
0
      } else {
1378
0
        zval_ptr_dtor(&local_retval);
1379
0
      }
1380
0
    } else {
1381
0
      if (retval_ptr) {
1382
0
        ZVAL_NULL(retval_ptr);
1383
0
      }
1384
0
    }
1385
1386
0
    EG(no_extensions)=0;
1387
0
    zend_destroy_static_vars(new_op_array);
1388
0
    destroy_op_array(new_op_array);
1389
0
    efree_size(new_op_array, sizeof(zend_op_array));
1390
0
    retval = SUCCESS;
1391
0
  } else {
1392
0
    retval = FAILURE;
1393
0
  }
1394
0
  zend_string_release(code_str);
1395
0
  return retval;
1396
0
}
1397
/* }}} */
1398
1399
ZEND_API zend_result zend_eval_string(const char *str, zval *retval_ptr, const char *string_name) /* {{{ */
1400
0
{
1401
0
  return zend_eval_stringl(str, strlen(str), retval_ptr, string_name);
1402
0
}
1403
/* }}} */
1404
1405
ZEND_API zend_result zend_eval_stringl_ex(const char *str, size_t str_len, zval *retval_ptr, const char *string_name, bool handle_exceptions) /* {{{ */
1406
0
{
1407
0
  zend_result result;
1408
1409
0
  result = zend_eval_stringl(str, str_len, retval_ptr, string_name);
1410
0
  if (handle_exceptions && EG(exception)) {
1411
0
    result = zend_exception_error(EG(exception), E_ERROR);
1412
0
  }
1413
0
  return result;
1414
0
}
1415
/* }}} */
1416
1417
ZEND_API zend_result zend_eval_string_ex(const char *str, zval *retval_ptr, const char *string_name, bool handle_exceptions) /* {{{ */
1418
0
{
1419
0
  return zend_eval_stringl_ex(str, strlen(str), retval_ptr, string_name, handle_exceptions);
1420
0
}
1421
/* }}} */
1422
1423
static void zend_set_timeout_ex(zend_long seconds, bool reset_signals);
1424
1425
ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */
1426
0
{
1427
#if defined(PHP_WIN32)
1428
# ifndef ZTS
1429
  /* No action is needed if we're timed out because zero seconds are
1430
     just ignored. Also, the hard timeout needs to be respected. If the
1431
     timer is not restarted properly, it could hang in the shutdown
1432
     function. */
1433
  if (EG(hard_timeout) > 0) {
1434
    zend_atomic_bool_store_ex(&EG(timed_out), false);
1435
    zend_set_timeout_ex(EG(hard_timeout), true);
1436
    /* XXX Abused, introduce an additional flag if the value needs to be kept. */
1437
    EG(hard_timeout) = 0;
1438
  }
1439
# endif
1440
#else
1441
0
  zend_atomic_bool_store_ex(&EG(timed_out), false);
1442
0
  zend_set_timeout_ex(0, true);
1443
0
#endif
1444
1445
0
  zend_error_noreturn(E_ERROR, "Maximum execution time of " ZEND_LONG_FMT " second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
1446
0
}
1447
/* }}} */
1448
1449
#ifndef ZEND_WIN32
1450
# ifdef ZEND_MAX_EXECUTION_TIMERS
1451
static void zend_timeout_handler(int dummy, siginfo_t *si, void *uc) /* {{{ */
1452
{
1453
#ifdef ZTS
1454
  if (!tsrm_is_managed_thread()) {
1455
    fprintf(stderr, "zend_timeout_handler() called in a thread not managed by PHP. The expected signal handler will not be called. This is probably a bug.\n");
1456
1457
    return;
1458
  }
1459
#endif
1460
1461
  if (si->si_value.sival_ptr != &EG(max_execution_timer_timer)) {
1462
#ifdef MAX_EXECUTION_TIMERS_DEBUG
1463
    fprintf(stderr, "Executing previous handler (if set) for unexpected signal SIGRTMIN received on thread %d\n", (pid_t) syscall(SYS_gettid));
1464
#endif
1465
1466
    if (EG(oldact).sa_sigaction) {
1467
      EG(oldact).sa_sigaction(dummy, si, uc);
1468
1469
      return;
1470
    }
1471
    if (EG(oldact).sa_handler) EG(oldact).sa_handler(dummy);
1472
1473
    return;
1474
  }
1475
# else
1476
static void zend_timeout_handler(int dummy) /* {{{ */
1477
0
{
1478
0
# endif
1479
#ifdef ZTS
1480
  if (!tsrm_is_managed_thread()) {
1481
    fprintf(stderr, "zend_timeout_handler() called in a thread not managed by PHP. The expected signal handler will not be called. This is probably a bug.\n");
1482
1483
    return;
1484
  }
1485
#else
1486
0
  if (zend_atomic_bool_load_ex(&EG(timed_out))) {
1487
    /* Die on hard timeout */
1488
0
    const char *error_filename = NULL;
1489
0
    uint32_t error_lineno = 0;
1490
0
    char log_buffer[2048];
1491
0
    int output_len = 0;
1492
1493
0
    if (zend_is_compiling()) {
1494
0
      error_filename = ZSTR_VAL(zend_get_compiled_filename());
1495
0
      error_lineno = zend_get_compiled_lineno();
1496
0
    } else if (zend_is_executing()) {
1497
0
      error_filename = zend_get_executed_filename();
1498
0
      if (error_filename[0] == '[') { /* [no active file] */
1499
0
        error_filename = NULL;
1500
0
        error_lineno = 0;
1501
0
      } else {
1502
0
        error_lineno = zend_get_executed_lineno();
1503
0
      }
1504
0
    }
1505
0
    if (!error_filename) {
1506
0
      error_filename = "Unknown";
1507
0
    }
1508
1509
0
    output_len = snprintf(log_buffer, sizeof(log_buffer), "\nFatal error: Maximum execution time of " ZEND_LONG_FMT "+" ZEND_LONG_FMT " seconds exceeded (terminated) in %s on line %d\n", EG(timeout_seconds), EG(hard_timeout), error_filename, error_lineno);
1510
0
    if (output_len > 0) {
1511
0
      zend_quiet_write(2, log_buffer, MIN(output_len, sizeof(log_buffer)));
1512
0
    }
1513
0
    _exit(124);
1514
0
  }
1515
0
#endif
1516
1517
0
  if (zend_on_timeout) {
1518
0
    zend_on_timeout(EG(timeout_seconds));
1519
0
  }
1520
1521
0
  zend_atomic_bool_store_ex(&EG(timed_out), true);
1522
0
  zend_atomic_bool_store_ex(&EG(vm_interrupt), true);
1523
1524
0
#ifndef ZTS
1525
0
  if (EG(hard_timeout) > 0) {
1526
    /* Set hard timeout */
1527
0
    zend_set_timeout_ex(EG(hard_timeout), true);
1528
0
  }
1529
0
#endif
1530
0
}
1531
/* }}} */
1532
#endif
1533
1534
#ifdef ZEND_WIN32
1535
VOID CALLBACK tq_timer_cb(PVOID arg, BOOLEAN timed_out)
1536
{
1537
  zend_executor_globals *eg;
1538
1539
  /* The doc states it'll be always true, however it theoretically
1540
    could be FALSE when the thread was signaled. */
1541
  if (!timed_out) {
1542
    return;
1543
  }
1544
1545
  eg = (zend_executor_globals *)arg;
1546
  zend_atomic_bool_store_ex(&eg->timed_out, true);
1547
  zend_atomic_bool_store_ex(&eg->vm_interrupt, true);
1548
}
1549
#endif
1550
1551
/* This one doesn't exists on QNX */
1552
#ifndef SIGPROF
1553
#define SIGPROF 27
1554
#endif
1555
1556
static void zend_set_timeout_ex(zend_long seconds, bool reset_signals) /* {{{ */
1557
247k
{
1558
#ifdef ZEND_WIN32
1559
  zend_executor_globals *eg;
1560
1561
  if (!seconds) {
1562
    return;
1563
  }
1564
1565
  /* Don't use ChangeTimerQueueTimer() as it will not restart an expired
1566
   * timer, so we could end up with just an ignored timeout. Instead
1567
   * delete and recreate. */
1568
  if (NULL != tq_timer) {
1569
    if (!DeleteTimerQueueTimer(NULL, tq_timer, INVALID_HANDLE_VALUE)) {
1570
      tq_timer = NULL;
1571
      zend_error_noreturn(E_ERROR, "Could not delete queued timer");
1572
      return;
1573
    }
1574
    tq_timer = NULL;
1575
  }
1576
1577
  /* XXX passing NULL means the default timer queue provided by the system is used */
1578
  eg = ZEND_MODULE_GLOBALS_BULK(executor);
1579
  if (!CreateTimerQueueTimer(&tq_timer, NULL, (WAITORTIMERCALLBACK)tq_timer_cb, (VOID*)eg, seconds*1000, 0, WT_EXECUTEONLYONCE)) {
1580
    tq_timer = NULL;
1581
    zend_error_noreturn(E_ERROR, "Could not queue new timer");
1582
    return;
1583
  }
1584
#elif defined(ZEND_MAX_EXECUTION_TIMERS)
1585
  if (seconds > 0) {
1586
    zend_max_execution_timer_settime(seconds);
1587
  }
1588
1589
  if (reset_signals) {
1590
    sigset_t sigset;
1591
    struct sigaction act;
1592
1593
    act.sa_sigaction = zend_timeout_handler;
1594
    sigemptyset(&act.sa_mask);
1595
    act.sa_flags = SA_ONSTACK | SA_SIGINFO;
1596
    sigaction(SIGRTMIN, &act, NULL);
1597
    sigemptyset(&sigset);
1598
    sigaddset(&sigset, SIGRTMIN);
1599
    sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1600
  }
1601
#elif defined(HAVE_SETITIMER)
1602
  {
1603
247k
    struct itimerval t_r;   /* timeout requested */
1604
247k
    int signo;
1605
1606
    // Prevent EINVAL error
1607
247k
    if (seconds < 0 || seconds > 999999999) {
1608
0
      seconds = 0;
1609
0
    }
1610
1611
247k
    if(seconds) {
1612
5
      t_r.it_value.tv_sec = seconds;
1613
5
      t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
1614
1615
# if defined(__CYGWIN__) || defined(__PASE__) || (defined(__aarch64__) && defined(__APPLE__))
1616
      // ITIMER_PROF is broken in Apple Silicon system with MacOS >= 14
1617
      // See https://openradar.appspot.com/radar?id=5583058442911744.
1618
      setitimer(ITIMER_REAL, &t_r, NULL);
1619
    }
1620
    signo = SIGALRM;
1621
# else
1622
5
      setitimer(ITIMER_PROF, &t_r, NULL);
1623
5
    }
1624
247k
    signo = SIGPROF;
1625
247k
# endif
1626
1627
247k
    if (reset_signals) {
1628
247k
# ifdef ZEND_SIGNALS
1629
247k
      zend_signal(signo, zend_timeout_handler);
1630
# else
1631
      sigset_t sigset;
1632
#  ifdef HAVE_SIGACTION
1633
      struct sigaction act;
1634
1635
      act.sa_handler = zend_timeout_handler;
1636
      sigemptyset(&act.sa_mask);
1637
      act.sa_flags = SA_ONSTACK | SA_RESETHAND | SA_NODEFER;
1638
      sigaction(signo, &act, NULL);
1639
#  else
1640
      signal(signo, zend_timeout_handler);
1641
#  endif /* HAVE_SIGACTION */
1642
      sigemptyset(&sigset);
1643
      sigaddset(&sigset, signo);
1644
      sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1645
# endif /* ZEND_SIGNALS */
1646
247k
    }
1647
247k
  }
1648
247k
#endif /* HAVE_SETITIMER */
1649
247k
}
1650
/* }}} */
1651
1652
void zend_set_timeout(zend_long seconds, bool reset_signals) /* {{{ */
1653
247k
{
1654
1655
247k
  EG(timeout_seconds) = seconds;
1656
247k
  zend_set_timeout_ex(seconds, reset_signals);
1657
247k
  zend_atomic_bool_store_ex(&EG(timed_out), false);
1658
247k
}
1659
/* }}} */
1660
1661
void zend_unset_timeout(void) /* {{{ */
1662
247k
{
1663
#ifdef ZEND_WIN32
1664
  if (NULL != tq_timer) {
1665
    if (!DeleteTimerQueueTimer(NULL, tq_timer, INVALID_HANDLE_VALUE)) {
1666
      zend_atomic_bool_store_ex(&EG(timed_out), false);
1667
      tq_timer = NULL;
1668
      zend_error_noreturn(E_ERROR, "Could not delete queued timer");
1669
      return;
1670
    }
1671
    tq_timer = NULL;
1672
  }
1673
#elif defined(ZEND_MAX_EXECUTION_TIMERS)
1674
  if (EG(timeout_seconds)) {
1675
    zend_max_execution_timer_settime(0);
1676
  }
1677
#elif defined(HAVE_SETITIMER)
1678
247k
  if (EG(timeout_seconds)) {
1679
10
    struct itimerval no_timeout;
1680
1681
10
    no_timeout.it_value.tv_sec = no_timeout.it_value.tv_usec = no_timeout.it_interval.tv_sec = no_timeout.it_interval.tv_usec = 0;
1682
1683
# if defined(__CYGWIN__) || defined(__PASE__) || (defined(__aarch64__) && defined(__APPLE__))
1684
    setitimer(ITIMER_REAL, &no_timeout, NULL);
1685
# else
1686
10
    setitimer(ITIMER_PROF, &no_timeout, NULL);
1687
10
# endif
1688
10
  }
1689
247k
#endif
1690
247k
  zend_atomic_bool_store_ex(&EG(timed_out), false);
1691
247k
}
1692
/* }}} */
1693
1694
static ZEND_COLD void report_class_fetch_error(const zend_string *class_name, uint32_t fetch_type)
1695
82.8k
{
1696
82.8k
  if (fetch_type & ZEND_FETCH_CLASS_SILENT) {
1697
81.4k
    return;
1698
81.4k
  }
1699
1700
1.37k
  if (EG(exception)) {
1701
230
    if (!(fetch_type & ZEND_FETCH_CLASS_EXCEPTION)) {
1702
0
      zend_exception_uncaught_error("During class fetch");
1703
0
    }
1704
230
    return;
1705
230
  }
1706
1707
1.14k
  if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) {
1708
35
    zend_throw_or_error(fetch_type, NULL, "Interface \"%s\" not found", ZSTR_VAL(class_name));
1709
1.10k
  } else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) {
1710
29
    zend_throw_or_error(fetch_type, NULL, "Trait \"%s\" not found", ZSTR_VAL(class_name));
1711
1.07k
  } else {
1712
1.07k
    zend_throw_or_error(fetch_type, NULL, "Class \"%s\" not found", ZSTR_VAL(class_name));
1713
1.07k
  }
1714
1.14k
}
1715
1716
zend_class_entry *zend_fetch_class(zend_string *class_name, uint32_t fetch_type) /* {{{ */
1717
5.00k
{
1718
5.00k
  zend_class_entry *ce, *scope;
1719
5.00k
  uint32_t fetch_sub_type = fetch_type & ZEND_FETCH_CLASS_MASK;
1720
1721
5.12k
check_fetch_type:
1722
5.12k
  switch (fetch_sub_type) {
1723
1.84k
    case ZEND_FETCH_CLASS_SELF:
1724
1.84k
      scope = zend_get_executed_scope();
1725
1.84k
      if (UNEXPECTED(!scope)) {
1726
47
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"self\" when no class scope is active");
1727
47
      }
1728
1.84k
      return scope;
1729
613
    case ZEND_FETCH_CLASS_PARENT:
1730
613
      scope = zend_get_executed_scope();
1731
613
      if (UNEXPECTED(!scope)) {
1732
15
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when no class scope is active");
1733
15
        return NULL;
1734
15
      }
1735
598
      if (UNEXPECTED(!scope->parent)) {
1736
0
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when current class scope has no parent");
1737
0
      }
1738
598
      return scope->parent;
1739
787
    case ZEND_FETCH_CLASS_STATIC:
1740
787
      ce = zend_get_called_scope(EG(current_execute_data));
1741
787
      if (UNEXPECTED(!ce)) {
1742
33
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"static\" when no class scope is active");
1743
33
        return NULL;
1744
33
      }
1745
754
      return ce;
1746
138
    case ZEND_FETCH_CLASS_AUTO: {
1747
138
        fetch_sub_type = zend_get_class_fetch_type(class_name);
1748
138
        if (UNEXPECTED(fetch_sub_type != ZEND_FETCH_CLASS_DEFAULT)) {
1749
118
          goto check_fetch_type;
1750
118
        }
1751
138
      }
1752
20
      break;
1753
5.12k
  }
1754
1755
1.75k
  ce = zend_lookup_class_ex(class_name, NULL, fetch_type);
1756
1.75k
  if (!ce) {
1757
129
    report_class_fetch_error(class_name, fetch_type);
1758
129
    return NULL;
1759
129
  }
1760
1.63k
  return ce;
1761
1.75k
}
1762
/* }}} */
1763
1764
zend_class_entry *zend_fetch_class_with_scope(
1765
    zend_string *class_name, uint32_t fetch_type, zend_class_entry *scope)
1766
417
{
1767
417
  zend_class_entry *ce;
1768
417
  switch (fetch_type & ZEND_FETCH_CLASS_MASK) {
1769
25
    case ZEND_FETCH_CLASS_SELF:
1770
25
      if (UNEXPECTED(!scope)) {
1771
5
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"self\" when no class scope is active");
1772
5
      }
1773
25
      return scope;
1774
10
    case ZEND_FETCH_CLASS_PARENT:
1775
10
      if (UNEXPECTED(!scope)) {
1776
0
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when no class scope is active");
1777
0
        return NULL;
1778
0
      }
1779
10
      if (UNEXPECTED(!scope->parent)) {
1780
5
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when current class scope has no parent");
1781
5
      }
1782
10
      return scope->parent;
1783
382
    case 0:
1784
382
      break;
1785
    /* Other fetch types are not supported by this function. */
1786
417
    EMPTY_SWITCH_DEFAULT_CASE()
1787
417
  }
1788
1789
382
  ce = zend_lookup_class_ex(class_name, NULL, fetch_type);
1790
382
  if (!ce) {
1791
24
    report_class_fetch_error(class_name, fetch_type);
1792
24
    return NULL;
1793
24
  }
1794
358
  return ce;
1795
382
}
1796
1797
zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *key, uint32_t fetch_type) /* {{{ */
1798
327k
{
1799
327k
  zend_class_entry *ce = zend_lookup_class_ex(class_name, key, fetch_type);
1800
327k
  if (!ce) {
1801
82.6k
    report_class_fetch_error(class_name, fetch_type);
1802
82.6k
    return NULL;
1803
82.6k
  }
1804
245k
  return ce;
1805
327k
}
1806
/* }}} */
1807
1808
ZEND_API zend_result zend_delete_global_variable(zend_string *name) /* {{{ */
1809
0
{
1810
0
  return zend_hash_del_ind(&EG(symbol_table), name);
1811
0
}
1812
/* }}} */
1813
1814
ZEND_API zend_array *zend_rebuild_symbol_table(void) /* {{{ */
1815
2.94k
{
1816
2.94k
  zend_execute_data *ex;
1817
2.94k
  zend_array *symbol_table;
1818
1819
  /* Search for last called user function */
1820
2.94k
  ex = EG(current_execute_data);
1821
3.07k
  while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) {
1822
131
    ex = ex->prev_execute_data;
1823
131
  }
1824
2.94k
  if (!ex) {
1825
0
    return NULL;
1826
0
  }
1827
2.94k
  if (ZEND_CALL_INFO(ex) & ZEND_CALL_HAS_SYMBOL_TABLE) {
1828
54
    return ex->symbol_table;
1829
54
  }
1830
1831
2.88k
  ZEND_ADD_CALL_FLAG(ex, ZEND_CALL_HAS_SYMBOL_TABLE);
1832
2.88k
  if (EG(symtable_cache_ptr) > EG(symtable_cache)) {
1833
726
    symbol_table = ex->symbol_table = *(--EG(symtable_cache_ptr));
1834
726
    if (!ex->func->op_array.last_var) {
1835
93
      return symbol_table;
1836
93
    }
1837
633
    zend_hash_extend(symbol_table, ex->func->op_array.last_var, 0);
1838
2.16k
  } else {
1839
2.16k
    symbol_table = ex->symbol_table = zend_new_array(ex->func->op_array.last_var);
1840
2.16k
    if (!ex->func->op_array.last_var) {
1841
98
      return symbol_table;
1842
98
    }
1843
2.06k
    zend_hash_real_init_mixed(symbol_table);
1844
    /*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
1845
2.06k
  }
1846
2.69k
  if (EXPECTED(ex->func->op_array.last_var)) {
1847
2.69k
    zend_string **str = ex->func->op_array.vars;
1848
2.69k
    zend_string **end = str + ex->func->op_array.last_var;
1849
2.69k
    zval *var = ZEND_CALL_VAR_NUM(ex, 0);
1850
1851
9.75k
    do {
1852
9.75k
      _zend_hash_append_ind(symbol_table, *str, var);
1853
9.75k
      str++;
1854
9.75k
      var++;
1855
9.75k
    } while (str != end);
1856
2.69k
  }
1857
2.69k
  return symbol_table;
1858
2.88k
}
1859
/* }}} */
1860
1861
ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ */
1862
109k
{
1863
109k
  const zend_op_array *op_array = &execute_data->func->op_array;
1864
109k
  HashTable *ht = execute_data->symbol_table;
1865
1866
  /* copy real values from symbol table into CV slots and create
1867
     INDIRECT references to CV in symbol table  */
1868
109k
  if (EXPECTED(op_array->last_var)) {
1869
109k
    zend_string **str = op_array->vars;
1870
109k
    zend_string **end = str + op_array->last_var;
1871
109k
    zval *var = EX_VAR_NUM(0);
1872
1873
855k
    do {
1874
855k
      zval *zv = zend_hash_find_known_hash(ht, *str);
1875
1876
855k
      if (zv) {
1877
510k
        if (Z_TYPE_P(zv) == IS_INDIRECT) {
1878
510k
          const zval *val = Z_INDIRECT_P(zv);
1879
1880
510k
          ZVAL_COPY_VALUE(var, val);
1881
510k
        } else {
1882
84
          ZVAL_COPY_VALUE(var, zv);
1883
84
        }
1884
510k
      } else {
1885
344k
        ZVAL_UNDEF(var);
1886
344k
        zv = zend_hash_add_new(ht, *str, var);
1887
344k
      }
1888
855k
      ZVAL_INDIRECT(zv, var);
1889
855k
      str++;
1890
855k
      var++;
1891
855k
    } while (str != end);
1892
109k
  }
1893
109k
}
1894
/* }}} */
1895
1896
ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ */
1897
40.4k
{
1898
40.4k
  const zend_op_array *op_array = &execute_data->func->op_array;
1899
40.4k
  HashTable *ht = execute_data->symbol_table;
1900
1901
  /* copy real values from CV slots into symbol table */
1902
40.4k
  if (EXPECTED(op_array->last_var)) {
1903
40.4k
    zend_string **str = op_array->vars;
1904
40.4k
    zend_string **end = str + op_array->last_var;
1905
40.4k
    zval *var = EX_VAR_NUM(0);
1906
1907
221k
    do {
1908
221k
      if (Z_TYPE_P(var) == IS_UNDEF) {
1909
52.0k
        zend_hash_del(ht, *str);
1910
169k
      } else {
1911
169k
        zend_hash_update(ht, *str, var);
1912
169k
        ZVAL_UNDEF(var);
1913
169k
      }
1914
221k
      str++;
1915
221k
      var++;
1916
221k
    } while (str != end);
1917
40.4k
  }
1918
40.4k
}
1919
/* }}} */
1920
1921
ZEND_API zend_result zend_set_local_var(zend_string *name, zval *value, bool force) /* {{{ */
1922
0
{
1923
0
  zend_execute_data *execute_data = EG(current_execute_data);
1924
1925
0
  while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
1926
0
    execute_data = execute_data->prev_execute_data;
1927
0
  }
1928
1929
0
  if (execute_data) {
1930
0
    if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) {
1931
0
      zend_ulong h = zend_string_hash_val(name);
1932
0
      const zend_op_array *op_array = &execute_data->func->op_array;
1933
1934
0
      if (EXPECTED(op_array->last_var)) {
1935
0
        zend_string **str = op_array->vars;
1936
0
        zend_string **end = str + op_array->last_var;
1937
1938
0
        do {
1939
0
          if (ZSTR_H(*str) == h &&
1940
0
              zend_string_equal_content(*str, name)) {
1941
0
            zval *var = EX_VAR_NUM(str - op_array->vars);
1942
0
            ZVAL_COPY_VALUE(var, value);
1943
0
            return SUCCESS;
1944
0
          }
1945
0
          str++;
1946
0
        } while (str != end);
1947
0
      }
1948
0
      if (force) {
1949
0
        zend_array *symbol_table = zend_rebuild_symbol_table();
1950
0
        if (symbol_table) {
1951
0
          zend_hash_update(symbol_table, name, value);
1952
0
          return SUCCESS;
1953
0
        }
1954
0
      }
1955
0
    } else {
1956
0
      zend_hash_update_ind(execute_data->symbol_table, name, value);
1957
0
      return SUCCESS;
1958
0
    }
1959
0
  }
1960
0
  return FAILURE;
1961
0
}
1962
/* }}} */
1963
1964
ZEND_API zend_result zend_set_local_var_str(const char *name, size_t len, zval *value, bool force) /* {{{ */
1965
0
{
1966
0
  zend_execute_data *execute_data = EG(current_execute_data);
1967
1968
0
  while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
1969
0
    execute_data = execute_data->prev_execute_data;
1970
0
  }
1971
1972
0
  if (execute_data) {
1973
0
    if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) {
1974
0
      zend_ulong h = zend_hash_func(name, len);
1975
0
      const zend_op_array *op_array = &execute_data->func->op_array;
1976
0
      if (EXPECTED(op_array->last_var)) {
1977
0
        zend_string **str = op_array->vars;
1978
0
        zend_string **end = str + op_array->last_var;
1979
1980
0
        do {
1981
0
          if (ZSTR_H(*str) == h &&
1982
0
              zend_string_equals_cstr(*str, name, len)) {
1983
0
            zval *var = EX_VAR_NUM(str - op_array->vars);
1984
0
            zval_ptr_dtor(var);
1985
0
            ZVAL_COPY_VALUE(var, value);
1986
0
            return SUCCESS;
1987
0
          }
1988
0
          str++;
1989
0
        } while (str != end);
1990
0
      }
1991
0
      if (force) {
1992
0
        zend_array *symbol_table = zend_rebuild_symbol_table();
1993
0
        if (symbol_table) {
1994
0
          zend_hash_str_update(symbol_table, name, len, value);
1995
0
          return SUCCESS;
1996
0
        }
1997
0
      }
1998
0
    } else {
1999
0
      zend_hash_str_update_ind(execute_data->symbol_table, name, len, value);
2000
0
      return SUCCESS;
2001
0
    }
2002
0
  }
2003
0
  return FAILURE;
2004
0
}
2005
/* }}} */