Coverage Report

Created: 2025-09-27 06:26

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