Coverage Report

Created: 2026-02-14 06:52

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