Coverage Report

Created: 2026-06-02 06:36

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