Coverage Report

Created: 2026-01-18 06:47

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