Coverage Report

Created: 2025-12-14 06:06

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