Coverage Report

Created: 2026-09-14 06:25

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