Coverage Report

Created: 2025-07-23 06:33

/src/php-src/Zend/zend_execute_API.c
Line
Count
Source (jump to first uncovered line)
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
104k
{
93
104k
  if (extension->activate) {
94
104k
    extension->activate();
95
104k
  }
96
104k
}
97
/* }}} */
98
99
static void zend_extension_deactivator(zend_extension *extension) /* {{{ */
100
104k
{
101
104k
  if (extension->deactivate) {
102
104k
    extension->deactivate();
103
104k
  }
104
104k
}
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
268k
{
130
268k
  zend_init_fpu();
131
132
268k
  ZVAL_NULL(&EG(uninitialized_zval));
133
268k
  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
268k
  ZVAL_UNDEF(&EG(last_fatal_error_backtrace));
140
141
268k
  EG(symtable_cache_ptr) = EG(symtable_cache);
142
268k
  EG(symtable_cache_limit) = EG(symtable_cache) + SYMTABLE_CACHE_SIZE;
143
268k
  EG(no_extensions) = 0;
144
145
268k
  EG(function_table) = CG(function_table);
146
268k
  EG(class_table) = CG(class_table);
147
148
268k
  EG(in_autoload) = NULL;
149
268k
  EG(error_handling) = EH_NORMAL;
150
268k
  EG(flags) = EG_FLAGS_INITIAL;
151
152
268k
  zend_vm_stack_init();
153
154
268k
  zend_hash_init(&EG(symbol_table), 64, NULL, ZVAL_PTR_DTOR, 0);
155
156
268k
  zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator);
157
158
268k
  zend_hash_init(&EG(included_files), 8, NULL, NULL, 0);
159
160
268k
  EG(ticks_count) = 0;
161
162
268k
  ZVAL_UNDEF(&EG(user_error_handler));
163
268k
  ZVAL_UNDEF(&EG(user_exception_handler));
164
165
268k
  EG(current_execute_data) = NULL;
166
167
268k
  zend_stack_init(&EG(user_error_handlers_error_reporting), sizeof(int));
168
268k
  zend_stack_init(&EG(user_error_handlers), sizeof(zval));
169
268k
  zend_stack_init(&EG(user_exception_handlers), sizeof(zval));
170
171
268k
  zend_objects_store_init(&EG(objects_store), 1024);
172
268k
  zend_lazy_objects_init(&EG(lazy_objects_store));
173
174
268k
  EG(full_tables_cleanup) = 0;
175
268k
  ZEND_ATOMIC_BOOL_INIT(&EG(vm_interrupt), false);
176
268k
  ZEND_ATOMIC_BOOL_INIT(&EG(timed_out), false);
177
178
268k
  EG(exception) = NULL;
179
268k
  EG(prev_exception) = NULL;
180
181
268k
  EG(fake_scope) = NULL;
182
268k
  EG(trampoline).common.function_name = NULL;
183
184
268k
  EG(ht_iterators_count) = sizeof(EG(ht_iterators_slots)) / sizeof(HashTableIterator);
185
268k
  EG(ht_iterators_used) = 0;
186
268k
  EG(ht_iterators) = EG(ht_iterators_slots);
187
268k
  memset(EG(ht_iterators), 0, sizeof(EG(ht_iterators_slots)));
188
189
268k
  EG(persistent_constants_count) = EG(zend_constants)->nNumUsed;
190
268k
  EG(persistent_functions_count) = EG(function_table)->nNumUsed;
191
268k
  EG(persistent_classes_count)   = EG(class_table)->nNumUsed;
192
193
268k
  EG(get_gc_buffer).start = EG(get_gc_buffer).end = EG(get_gc_buffer).cur = NULL;
194
195
268k
  EG(record_errors) = false;
196
268k
  EG(num_errors) = 0;
197
268k
  EG(errors) = NULL;
198
199
268k
  EG(filename_override) = NULL;
200
268k
  EG(lineno_override) = -1;
201
202
268k
  zend_max_execution_timer_init();
203
268k
  zend_fiber_init();
204
268k
  zend_weakrefs_init();
205
206
268k
  EG(active) = 1;
207
268k
}
208
/* }}} */
209
210
static int zval_call_destructor(zval *zv) /* {{{ */
211
1.80M
{
212
1.80M
  if (Z_TYPE_P(zv) == IS_INDIRECT) {
213
322k
    zv = Z_INDIRECT_P(zv);
214
322k
  }
215
1.80M
  if (Z_TYPE_P(zv) == IS_OBJECT && Z_REFCOUNT_P(zv) == 1) {
216
41.7k
    return ZEND_HASH_APPLY_REMOVE;
217
1.76M
  } else {
218
1.76M
    return ZEND_HASH_APPLY_KEEP;
219
1.76M
  }
220
1.80M
}
221
/* }}} */
222
223
static void zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */
224
277k
{
225
277k
  if (Z_TYPE_P(zv) == IS_INDIRECT) {
226
179k
    zv = Z_INDIRECT_P(zv);
227
179k
  }
228
277k
  i_zval_ptr_dtor(zv);
229
277k
}
230
/* }}} */
231
232
static ZEND_COLD void zend_throw_or_error(int fetch_type, zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
233
2.18k
{
234
2.18k
  va_list va;
235
2.18k
  char *message = NULL;
236
237
2.18k
  va_start(va, format);
238
2.18k
  zend_vspprintf(&message, 0, format, va);
239
240
2.18k
  if (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) {
241
2.18k
    zend_throw_error(exception_ce, "%s", message);
242
2.18k
  } else {
243
0
    zend_error_noreturn(E_ERROR, "%s", message);
244
0
  }
245
246
2.18k
  efree(message);
247
2.18k
  va_end(va);
248
2.18k
}
249
/* }}} */
250
251
void shutdown_destructors(void) /* {{{ */
252
268k
{
253
268k
  if (CG(unclean_shutdown)) {
254
23.9k
    EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
255
23.9k
  }
256
268k
  zend_try {
257
268k
    uint32_t symbols;
258
297k
    do {
259
297k
      symbols = zend_hash_num_elements(&EG(symbol_table));
260
297k
      zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor);
261
297k
    } while (symbols != zend_hash_num_elements(&EG(symbol_table)));
262
268k
    zend_objects_store_call_destructors(&EG(objects_store));
263
268k
  } 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
268k
}
268
/* }}} */
269
270
/* Free values held by the executor. */
271
ZEND_API void zend_shutdown_executor_values(bool fast_shutdown)
272
268k
{
273
268k
  zend_string *key;
274
268k
  zval *zv;
275
276
268k
  EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN;
277
268k
  zend_try {
278
268k
    zend_close_rsrc_list(&EG(regular_list));
279
268k
  } zend_end_try();
280
281
  /* No PHP callback functions should be called after this point. */
282
268k
  EG(active) = 0;
283
284
268k
  if (!fast_shutdown) {
285
268k
    zend_hash_graceful_reverse_destroy(&EG(symbol_table));
286
287
    /* Constants may contain objects, destroy them before the object store. */
288
268k
    if (EG(full_tables_cleanup)) {
289
0
      zend_hash_reverse_apply(EG(zend_constants), clean_non_persistent_constant_full);
290
268k
    } else {
291
1.07M
      ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(zend_constants), key, zv) {
292
1.07M
        zend_constant *c = Z_PTR_P(zv);
293
1.07M
        if (_idx == EG(persistent_constants_count)) {
294
268k
          break;
295
268k
        }
296
2.69k
        zval_ptr_dtor_nogc(&c->value);
297
2.69k
        if (c->name) {
298
2.69k
          zend_string_release_ex(c->name, 0);
299
2.69k
        }
300
2.69k
        if (c->filename) {
301
2.61k
          zend_string_release_ex(c->filename, 0);
302
2.61k
        }
303
2.69k
        if (c->attributes) {
304
156
          zend_hash_release(c->attributes);
305
156
        }
306
2.69k
        efree(c);
307
2.69k
        zend_string_release_ex(key, 0);
308
2.69k
      } ZEND_HASH_MAP_FOREACH_END_DEL();
309
268k
    }
310
311
268k
    zval_ptr_dtor(&EG(last_fatal_error_backtrace));
312
268k
    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.10M
    ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(function_table), zv) {
317
1.10M
      zend_op_array *op_array = Z_PTR_P(zv);
318
1.10M
      if (op_array->type == ZEND_INTERNAL_FUNCTION) {
319
268k
        break;
320
268k
      }
321
18.0k
      if (ZEND_MAP_PTR(op_array->static_variables_ptr)) {
322
292
        HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
323
292
        if (ht) {
324
257
          zend_array_destroy(ht);
325
257
          ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
326
257
        }
327
292
      }
328
18.0k
    } ZEND_HASH_FOREACH_END();
329
88.1M
    ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) {
330
88.1M
      zend_class_entry *ce = Z_PTR_P(zv);
331
332
88.1M
      if (ce->default_static_members_count) {
333
3.78k
        zend_cleanup_internal_class_data(ce);
334
3.78k
      }
335
336
88.1M
      if (ZEND_MAP_PTR(ce->mutable_data)) {
337
1.34M
        if (ZEND_MAP_PTR_GET_IMM(ce->mutable_data)) {
338
741
          zend_cleanup_mutable_class_data(ce);
339
741
        }
340
42.4M
      } 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
44.5k
        zend_class_constant *c;
343
108k
        ZEND_HASH_MAP_FOREACH_PTR(&ce->constants_table, c) {
344
108k
          if (c->ce == ce) {
345
5.00k
            zval_ptr_dtor_nogc(&c->value);
346
5.00k
            ZVAL_UNDEF(&c->value);
347
5.00k
          }
348
108k
        } ZEND_HASH_FOREACH_END();
349
350
        /* properties may contain objects as well */
351
44.5k
        if (ce->default_properties_table) {
352
15.7k
          zval *p = ce->default_properties_table;
353
15.7k
          zval *end = p + ce->default_properties_count;
354
355
36.8k
          while (p != end) {
356
21.0k
            i_zval_ptr_dtor(p);
357
21.0k
            ZVAL_UNDEF(p);
358
21.0k
            p++;
359
21.0k
          }
360
15.7k
        }
361
44.5k
      }
362
363
43.8M
      if (ce->type == ZEND_USER_CLASS && ce->backed_enum_table) {
364
265
        ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_IMMUTABLE));
365
265
        zend_hash_release(ce->backed_enum_table);
366
265
        ce->backed_enum_table = NULL;
367
265
      }
368
369
43.8M
      if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
370
375
        zend_op_array *op_array;
371
1.69k
        ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) {
372
1.69k
          if (op_array->type == ZEND_USER_FUNCTION) {
373
473
            if (ZEND_MAP_PTR(op_array->static_variables_ptr)) {
374
229
              HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
375
229
              if (ht) {
376
133
                zend_array_destroy(ht);
377
133
                ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
378
133
              }
379
229
            }
380
473
          }
381
1.69k
        } ZEND_HASH_FOREACH_END();
382
383
375
        if (ce->num_hooked_props) {
384
26
          zend_property_info *prop_info;
385
126
          ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop_info) {
386
126
            if (prop_info->ce == ce) {
387
37
              if (prop_info->hooks) {
388
78
                for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
389
52
                  if (prop_info->hooks[i]) {
390
26
                    ZEND_ASSERT(ZEND_USER_CODE(prop_info->hooks[i]->type));
391
26
                    op_array = &prop_info->hooks[i]->op_array;
392
26
                    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
26
                  }
400
52
                }
401
26
              }
402
37
            }
403
126
          } ZEND_HASH_FOREACH_END();
404
26
        }
405
375
      }
406
43.8M
    } ZEND_HASH_FOREACH_END();
407
408
    /* Also release error and exception handlers, which may hold objects. */
409
268k
    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
268k
    if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
415
67
      zval_ptr_dtor(&EG(user_exception_handler));
416
67
      ZVAL_UNDEF(&EG(user_exception_handler));
417
67
    }
418
419
268k
    zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1);
420
268k
    zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
421
268k
    zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
422
423
268k
#if ZEND_DEBUG
424
268k
    if (!CG(unclean_shutdown)) {
425
243k
      gc_collect_cycles();
426
243k
    }
427
268k
#endif
428
268k
  } else {
429
0
    zend_hash_discard(EG(zend_constants), EG(persistent_constants_count));
430
0
  }
431
432
268k
  zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown);
433
268k
}
434
435
void shutdown_executor(void) /* {{{ */
436
268k
{
437
268k
  zend_string *key;
438
268k
  zval *zv;
439
268k
#if ZEND_DEBUG
440
268k
  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
268k
  zend_try {
452
268k
    zend_stream_shutdown();
453
268k
  } zend_end_try();
454
455
268k
  zend_shutdown_executor_values(fast_shutdown);
456
457
268k
  zend_weakrefs_shutdown();
458
268k
  zend_max_execution_timer_shutdown();
459
268k
  zend_fiber_shutdown();
460
461
268k
  zend_try {
462
268k
    zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
463
268k
  } zend_end_try();
464
465
268k
  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
268k
  } else {
474
268k
    zend_vm_stack_destroy();
475
476
268k
    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
268k
    } else {
480
1.10M
      ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(function_table), key, zv) {
481
1.10M
        zend_function *func = Z_PTR_P(zv);
482
1.10M
        if (_idx == EG(persistent_functions_count)) {
483
268k
          break;
484
268k
        }
485
18.0k
        destroy_op_array(&func->op_array);
486
18.0k
        zend_string_release_ex(key, 0);
487
18.0k
      } ZEND_HASH_MAP_FOREACH_END_DEL();
488
489
1.21M
      ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) {
490
1.21M
        if (_idx == EG(persistent_classes_count)) {
491
268k
          break;
492
268k
        }
493
72.6k
        destroy_zend_class(zv);
494
72.6k
        zend_string_release_ex(key, 0);
495
72.6k
      } ZEND_HASH_MAP_FOREACH_END_DEL();
496
268k
    }
497
498
269k
    while (EG(symtable_cache_ptr) > EG(symtable_cache)) {
499
1.01k
      EG(symtable_cache_ptr)--;
500
1.01k
      zend_hash_destroy(*EG(symtable_cache_ptr));
501
1.01k
      FREE_HASHTABLE(*EG(symtable_cache_ptr));
502
1.01k
    }
503
504
268k
    zend_hash_destroy(&EG(included_files));
505
506
268k
    zend_stack_destroy(&EG(user_error_handlers_error_reporting));
507
268k
    zend_stack_destroy(&EG(user_error_handlers));
508
268k
    zend_stack_destroy(&EG(user_exception_handlers));
509
268k
    zend_lazy_objects_destroy(&EG(lazy_objects_store));
510
268k
    zend_objects_store_destroy(&EG(objects_store));
511
268k
    if (EG(in_autoload)) {
512
6.92k
      zend_hash_destroy(EG(in_autoload));
513
6.92k
      FREE_HASHTABLE(EG(in_autoload));
514
6.92k
    }
515
516
268k
    if (EG(ht_iterators) != EG(ht_iterators_slots)) {
517
0
      efree(EG(ht_iterators));
518
0
    }
519
268k
  }
520
521
268k
#if ZEND_DEBUG
522
268k
  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
268k
#endif
526
527
  /* Check whether anyone is hogging the trampoline. */
528
268k
  ZEND_ASSERT(EG(trampoline).common.function_name == NULL || CG(unclean_shutdown));
529
530
268k
  EG(ht_iterators_used) = 0;
531
532
268k
  zend_shutdown_fpu();
533
268k
}
534
/* }}} */
535
536
/* return class name and "::" or "". */
537
ZEND_API const char *get_active_class_name(const char **space) /* {{{ */
538
10
{
539
10
  zend_function *func;
540
541
10
  if (!zend_is_executing()) {
542
0
    if (space) {
543
0
      *space = "";
544
0
    }
545
0
    return "";
546
0
  }
547
548
10
  func = zend_active_function();
549
550
10
  switch (func->type) {
551
0
    case ZEND_USER_FUNCTION:
552
10
    case ZEND_INTERNAL_FUNCTION:
553
10
    {
554
10
      zend_class_entry *ce = func->common.scope;
555
556
10
      if (space) {
557
10
        *space = ce ? "::" : "";
558
10
      }
559
10
      return ce ? ZSTR_VAL(ce->name) : "";
560
0
    }
561
0
    default:
562
0
      if (space) {
563
0
        *space = "";
564
0
      }
565
0
      return "";
566
10
  }
567
10
}
568
/* }}} */
569
570
ZEND_API const char *get_active_function_name(void) /* {{{ */
571
52
{
572
52
  zend_function *func;
573
574
52
  if (!zend_is_executing()) {
575
0
    return NULL;
576
0
  }
577
578
52
  func = zend_active_function();
579
580
52
  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
52
    case ZEND_INTERNAL_FUNCTION:
592
52
      return ZSTR_VAL(func->common.function_name);
593
0
      break;
594
0
    default:
595
0
      return NULL;
596
52
  }
597
52
}
598
/* }}} */
599
600
ZEND_API zend_function *zend_active_function_ex(zend_execute_data *execute_data)
601
1.44k
{
602
1.44k
  zend_function *func = EX(func);
603
604
  /* Resolve function if op is a frameless call. */
605
1.44k
  if (ZEND_USER_CODE(func->type)) {
606
1.44k
    const zend_op *op = EX(opline);
607
1.44k
    if (ZEND_OP_IS_FRAMELESS_ICALL(op->opcode)) {
608
0
      func = ZEND_FLF_FUNC(op);
609
0
    }
610
1.44k
  }
611
612
1.44k
  return func;
613
1.44k
}
614
615
ZEND_API zend_string *get_active_function_or_method_name(void) /* {{{ */
616
7.38k
{
617
7.38k
  ZEND_ASSERT(zend_is_executing());
618
619
7.38k
  return get_function_or_method_name(zend_active_function());
620
7.38k
}
621
/* }}} */
622
623
ZEND_API zend_string *get_function_or_method_name(const zend_function *func) /* {{{ */
624
8.61k
{
625
8.61k
  if (func->common.scope && func->common.function_name) {
626
4.45k
    return zend_create_member_string(func->common.scope->name, func->common.function_name);
627
4.45k
  }
628
629
4.16k
  return func->common.function_name ? zend_string_copy(func->common.function_name) : ZSTR_INIT_LITERAL("main", 0);
630
8.61k
}
631
/* }}} */
632
633
ZEND_API const char *get_active_function_arg_name(uint32_t arg_num) /* {{{ */
634
6.67k
{
635
6.67k
  if (!zend_is_executing()) {
636
0
    return NULL;
637
0
  }
638
639
6.67k
  zend_function *func = zend_active_function();
640
641
6.67k
  return get_function_arg_name(func, arg_num);
642
6.67k
}
643
/* }}} */
644
645
ZEND_API const char *get_function_arg_name(const zend_function *func, uint32_t arg_num) /* {{{ */
646
7.16k
{
647
7.16k
  if (!func || arg_num == 0 || func->common.num_args < arg_num) {
648
45
    return NULL;
649
45
  }
650
651
7.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
6.01k
  } else {
654
6.01k
    return ((zend_internal_arg_info*) func->common.arg_info)[arg_num - 1].name;
655
6.01k
  }
656
7.12k
}
657
/* }}} */
658
659
ZEND_API const char *zend_get_executed_filename(void) /* {{{ */
660
1.12M
{
661
1.12M
  zend_string *filename = zend_get_executed_filename_ex();
662
1.12M
  return filename != NULL ? ZSTR_VAL(filename) : "[no active file]";
663
1.12M
}
664
/* }}} */
665
666
ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */
667
4.10M
{
668
4.10M
  zend_string *filename_override = EG(filename_override);
669
4.10M
  if (filename_override != NULL) {
670
199
    return filename_override;
671
199
  }
672
673
4.10M
  zend_execute_data *ex = EG(current_execute_data);
674
675
6.01M
  while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
676
1.90M
    ex = ex->prev_execute_data;
677
1.90M
  }
678
4.10M
  if (ex) {
679
2.85M
    return ex->func->op_array.filename;
680
2.85M
  } else {
681
1.24M
    return NULL;
682
1.24M
  }
683
4.10M
}
684
/* }}} */
685
686
ZEND_API uint32_t zend_get_executed_lineno(void) /* {{{ */
687
4.02M
{
688
4.02M
  zend_long lineno_override = EG(lineno_override);
689
4.02M
  if (lineno_override != -1) {
690
199
    return lineno_override;
691
199
  }
692
693
4.02M
  zend_execute_data *ex = EG(current_execute_data);
694
695
5.93M
  while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
696
1.90M
    ex = ex->prev_execute_data;
697
1.90M
  }
698
4.02M
  if (ex) {
699
2.78M
    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.78M
    if (EG(exception) && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
704
2.78M
        ex->opline->lineno == 0 && EG(opline_before_exception)) {
705
47
      return EG(opline_before_exception)->lineno;
706
47
    }
707
2.78M
    return ex->opline->lineno;
708
2.78M
  } else {
709
1.24M
    return 0;
710
1.24M
  }
711
4.02M
}
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.5k
  while (1) {
719
12.5k
    if (!ex) {
720
20
      return NULL;
721
12.5k
    } 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.25k
    ex = ex->prev_execute_data;
725
1.25k
  }
726
11.2k
}
727
/* }}} */
728
729
ZEND_API bool zend_is_executing(void) /* {{{ */
730
3.30M
{
731
3.30M
  return EG(current_execute_data) != 0;
732
3.30M
}
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.18k
{
737
5.18k
  if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
738
5.18k
    zend_ast *ast = Z_ASTVAL_P(p);
739
740
5.18k
    if (ast->kind == ZEND_AST_CONSTANT) {
741
582
      zend_string *name = zend_ast_get_constant_name(ast);
742
582
      zval *zv = zend_get_constant_ex(name, scope, ast->attr);
743
582
      if (UNEXPECTED(zv == NULL)) {
744
85
        return FAILURE;
745
85
      }
746
747
497
      zval_ptr_dtor_nogc(p);
748
497
      ZVAL_COPY_OR_DUP(p, zv);
749
4.60k
    } else {
750
4.60k
      zval tmp;
751
4.60k
      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.60k
      zend_ast_ref *ast_ref = Z_AST_P(p);
757
4.60k
      bool ast_is_refcounted = !(GC_FLAGS(ast_ref) & GC_IMMUTABLE);
758
4.60k
      if (ast_is_refcounted) {
759
195
        GC_ADDREF(ast_ref);
760
195
      }
761
4.60k
      zend_result result = zend_ast_evaluate_ex(&tmp, ast, scope, &short_circuited, ctx) != SUCCESS;
762
4.60k
      if (ast_is_refcounted && !GC_DELREF(ast_ref)) {
763
6
        rc_dtor_func((zend_refcounted *)ast_ref);
764
6
      }
765
4.60k
      if (UNEXPECTED(result != SUCCESS)) {
766
513
        return FAILURE;
767
513
      }
768
4.09k
      zval_ptr_dtor_nogc(p);
769
4.09k
      ZVAL_COPY_VALUE(p, &tmp);
770
4.09k
    }
771
5.18k
  }
772
4.58k
  return SUCCESS;
773
5.18k
}
774
/* }}} */
775
776
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_ex(zval *p, zend_class_entry *scope)
777
4.65k
{
778
4.65k
  zend_ast_evaluate_ctx ctx = {0};
779
4.65k
  return zval_update_constant_with_ctx(p, scope, &ctx);
780
4.65k
}
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
44
{
790
44
  zend_fcall_info fci;
791
792
44
  fci.size = sizeof(fci);
793
44
  if (object) {
794
20
    ZEND_ASSERT(Z_TYPE_P(object) == IS_OBJECT);
795
20
    fci.object = Z_OBJ_P(object);
796
24
  } else {
797
24
    fci.object = NULL;
798
24
  }
799
44
  ZVAL_COPY_VALUE(&fci.function_name, function_name);
800
44
  fci.retval = retval_ptr;
801
44
  fci.param_count = param_count;
802
44
  fci.params = params;
803
44
  fci.named_params = named_params;
804
805
44
  return zend_call_function(&fci, NULL);
806
44
}
807
/* }}} */
808
809
zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /* {{{ */
810
918k
{
811
918k
  uint32_t i;
812
918k
  zend_execute_data *call;
813
918k
  zend_fcall_info_cache fci_cache_local;
814
918k
  zend_function *func;
815
918k
  uint32_t call_info;
816
918k
  void *object_or_called_scope;
817
818
918k
  ZVAL_UNDEF(fci->retval);
819
820
918k
  if (!EG(active)) {
821
0
    return FAILURE; /* executor is already inactive */
822
0
  }
823
824
918k
  if (EG(exception)) {
825
1.03k
    if (fci_cache) {
826
1.03k
      zend_release_fcall_info_cache(fci_cache);
827
1.03k
    }
828
1.03k
    return SUCCESS; /* we would result in an unstable executor otherwise */
829
1.03k
  }
830
831
917k
  ZEND_ASSERT(ZEND_FCI_INITIALIZED(*fci));
832
833
917k
  if (!fci_cache || !fci_cache->function_handler) {
834
5.65k
    char *error = NULL;
835
836
5.65k
    if (!fci_cache) {
837
5.62k
      fci_cache = &fci_cache_local;
838
5.62k
    }
839
840
5.65k
    if (!zend_is_callable_ex(&fci->function_name, fci->object, 0, NULL, fci_cache, &error)) {
841
12
      ZEND_ASSERT(error && "Should have error if not callable");
842
12
      zend_string *callable_name
843
12
        = zend_get_callable_name_ex(&fci->function_name, fci->object);
844
12
      zend_throw_error(NULL, "Invalid callback %s, %s", ZSTR_VAL(callable_name), error);
845
12
      efree(error);
846
12
      zend_string_release_ex(callable_name, 0);
847
12
      return SUCCESS;
848
12
    }
849
850
5.64k
    ZEND_ASSERT(!error);
851
5.64k
  }
852
853
917k
  func = fci_cache->function_handler;
854
917k
  if ((func->common.fn_flags & ZEND_ACC_STATIC) || !fci_cache->object) {
855
102k
    object_or_called_scope = fci_cache->called_scope;
856
102k
    call_info = ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC;
857
815k
  } else {
858
815k
    object_or_called_scope = fci_cache->object;
859
815k
    call_info = ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC | ZEND_CALL_HAS_THIS;
860
815k
  }
861
862
917k
  call = zend_vm_stack_push_call_frame(call_info,
863
917k
    func, fci->param_count, object_or_called_scope);
864
865
917k
  if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_DEPRECATED)) {
866
7
    zend_deprecated_function(func);
867
868
7
    if (UNEXPECTED(EG(exception))) {
869
0
      zend_vm_stack_free_call_frame(call);
870
0
      return SUCCESS;
871
0
    }
872
7
  }
873
874
1.62M
  for (i=0; i<fci->param_count; i++) {
875
705k
    zval *param = ZEND_CALL_ARG(call, i+1);
876
705k
    zval *arg = &fci->params[i];
877
705k
    bool must_wrap = 0;
878
705k
    if (UNEXPECTED(Z_ISUNDEF_P(arg))) {
879
      /* Allow forwarding undef slots. This is only used by Closure::__invoke(). */
880
12
      ZVAL_UNDEF(param);
881
12
      ZEND_ADD_CALL_FLAG(call, ZEND_CALL_MAY_HAVE_UNDEF);
882
12
      continue;
883
12
    }
884
885
705k
    if (ARG_SHOULD_BE_SENT_BY_REF(func, i + 1)) {
886
254
      if (UNEXPECTED(!Z_ISREF_P(arg))) {
887
58
        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
40
          zend_param_must_be_ref(func, i + 1);
891
40
          must_wrap = 1;
892
40
          if (UNEXPECTED(EG(exception))) {
893
0
            ZEND_CALL_NUM_ARGS(call) = i;
894
32
cleanup_args:
895
32
            zend_vm_stack_free_args(call);
896
32
            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
32
            zend_vm_stack_free_call_frame(call);
900
32
            zend_release_fcall_info_cache(fci_cache);
901
32
            return SUCCESS;
902
0
          }
903
40
        }
904
58
      }
905
704k
    } else {
906
704k
      if (Z_ISREF_P(arg) &&
907
704k
          !(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
908
        /* don't separate references for __call */
909
34
        arg = Z_REFVAL_P(arg);
910
34
      }
911
704k
    }
912
913
705k
    if (EXPECTED(!must_wrap)) {
914
705k
      ZVAL_COPY(param, arg);
915
705k
    } else {
916
40
      Z_TRY_ADDREF_P(arg);
917
40
      ZVAL_NEW_REF(param, arg);
918
40
    }
919
705k
  }
920
921
917k
  if (fci->named_params) {
922
577
    zend_string *name;
923
577
    zval *arg;
924
577
    uint32_t arg_num = ZEND_CALL_NUM_ARGS(call) + 1;
925
577
    bool have_named_params = 0;
926
2.34k
    ZEND_HASH_FOREACH_STR_KEY_VAL(fci->named_params, name, arg) {
927
2.34k
      bool must_wrap = 0;
928
2.34k
      zval *target;
929
2.34k
      if (name) {
930
643
        void *cache_slot[2] = {NULL, NULL};
931
643
        have_named_params = 1;
932
643
        target = zend_handle_named_arg(&call, name, &arg_num, cache_slot);
933
643
        if (!target) {
934
19
          goto cleanup_args;
935
19
        }
936
643
      } else {
937
239
        if (have_named_params) {
938
13
          zend_throw_error(NULL,
939
13
            "Cannot use positional argument after named argument");
940
13
          goto cleanup_args;
941
13
        }
942
943
226
        zend_vm_stack_extend_call_frame(&call, arg_num - 1, 1);
944
226
        target = ZEND_CALL_ARG(call, arg_num);
945
226
      }
946
947
850
      if (ARG_SHOULD_BE_SENT_BY_REF(func, arg_num)) {
948
48
        if (UNEXPECTED(!Z_ISREF_P(arg))) {
949
48
          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
38
            zend_param_must_be_ref(func, arg_num);
953
38
            must_wrap = 1;
954
38
            if (UNEXPECTED(EG(exception))) {
955
0
              goto cleanup_args;
956
0
            }
957
38
          }
958
48
        }
959
802
      } else {
960
802
        if (Z_ISREF_P(arg) &&
961
802
          !(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
802
      }
966
967
850
      if (EXPECTED(!must_wrap)) {
968
812
        ZVAL_COPY(target, arg);
969
812
      } else {
970
38
        Z_TRY_ADDREF_P(arg);
971
38
        ZVAL_NEW_REF(target, arg);
972
38
      }
973
850
      if (!name) {
974
226
        ZEND_CALL_NUM_ARGS(call)++;
975
226
        arg_num++;
976
226
      }
977
850
    } ZEND_HASH_FOREACH_END();
978
577
  }
979
980
917k
  if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_MAY_HAVE_UNDEF)) {
981
    /* zend_handle_undef_args assumes prev_execute_data is initialized. */
982
372
    call->prev_execute_data = NULL;
983
372
    if (zend_handle_undef_args(call) == FAILURE) {
984
24
      zend_vm_stack_free_args(call);
985
24
      zend_vm_stack_free_call_frame(call);
986
24
      return SUCCESS;
987
24
    }
988
372
  }
989
990
917k
  if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
991
6.31k
    uint32_t call_info;
992
993
6.31k
    GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
994
6.31k
    call_info = ZEND_CALL_CLOSURE;
995
6.31k
    if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
996
91
      call_info |= ZEND_CALL_FAKE_CLOSURE;
997
91
    }
998
6.31k
    ZEND_ADD_CALL_FLAG(call, call_info);
999
6.31k
  }
1000
1001
917k
  if (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
1002
106
    fci_cache->function_handler = NULL;
1003
106
  }
1004
1005
917k
  const zend_class_entry *orig_fake_scope = EG(fake_scope);
1006
917k
  EG(fake_scope) = NULL;
1007
917k
  if (func->type == ZEND_USER_FUNCTION) {
1008
303k
    uint32_t orig_jit_trace_num = EG(jit_trace_num);
1009
1010
303k
    zend_init_func_execute_data(call, &func->op_array, fci->retval);
1011
303k
    ZEND_OBSERVER_FCALL_BEGIN(call);
1012
303k
    zend_execute_ex(call);
1013
303k
    EG(jit_trace_num) = orig_jit_trace_num;
1014
614k
  } else {
1015
614k
    ZEND_ASSERT(func->type == ZEND_INTERNAL_FUNCTION);
1016
614k
    ZVAL_NULL(fci->retval);
1017
614k
    call->prev_execute_data = EG(current_execute_data);
1018
614k
    EG(current_execute_data) = call;
1019
614k
#if ZEND_DEBUG
1020
614k
    bool should_throw = zend_internal_call_should_throw(func, call);
1021
614k
#endif
1022
614k
    ZEND_OBSERVER_FCALL_BEGIN(call);
1023
614k
    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
98.9k
      zend_execute_internal(call, fci->retval);
1028
98.9k
    }
1029
1030
614k
#if ZEND_DEBUG
1031
614k
    if (!EG(exception) && call->func) {
1032
532k
      if (should_throw) {
1033
0
        zend_internal_call_arginfo_violation(call->func);
1034
0
      }
1035
532k
      ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
1036
532k
        zend_verify_internal_return_type(call->func, fci->retval));
1037
532k
      ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
1038
532k
        ? Z_ISREF_P(fci->retval) : !Z_ISREF_P(fci->retval));
1039
532k
    }
1040
614k
#endif
1041
614k
    ZEND_OBSERVER_FCALL_END(call, fci->retval);
1042
614k
    EG(current_execute_data) = call->prev_execute_data;
1043
614k
    zend_vm_stack_free_args(call);
1044
614k
    if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
1045
12
      zend_array_release(call->extra_named_params);
1046
12
    }
1047
1048
614k
    if (EG(exception)) {
1049
81.9k
      zval_ptr_dtor(fci->retval);
1050
81.9k
      ZVAL_UNDEF(fci->retval);
1051
81.9k
    }
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
614k
    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
614k
    if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) {
1064
38
      OBJ_RELEASE(Z_OBJ(call->This));
1065
38
    }
1066
614k
  }
1067
917k
  EG(fake_scope) = orig_fake_scope;
1068
1069
917k
  zend_vm_stack_free_call_frame(call);
1070
1071
917k
  if (UNEXPECTED(EG(exception))) {
1072
84.7k
    if (UNEXPECTED(!EG(current_execute_data))) {
1073
186
      zend_throw_exception_internal(NULL);
1074
84.5k
    } else if (EG(current_execute_data)->func &&
1075
84.5k
               ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
1076
1.80k
      zend_rethrow_exception(EG(current_execute_data));
1077
1.80k
    }
1078
84.7k
  }
1079
1080
917k
  return SUCCESS;
1081
917k
}
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
906k
{
1088
906k
  zval retval;
1089
906k
  zend_fcall_info fci;
1090
906k
  zend_fcall_info_cache fcic;
1091
1092
906k
  ZEND_ASSERT(fn && "zend_function must be passed!");
1093
1094
906k
  fci.size = sizeof(fci);
1095
906k
  fci.object = object;
1096
906k
  fci.retval = retval_ptr ? retval_ptr : &retval;
1097
906k
  fci.param_count = param_count;
1098
906k
  fci.params = params;
1099
906k
  fci.named_params = named_params;
1100
906k
  ZVAL_UNDEF(&fci.function_name); /* Unused */
1101
1102
906k
  fcic.function_handler = fn;
1103
906k
  fcic.object = object;
1104
906k
  fcic.called_scope = called_scope;
1105
1106
906k
  zend_result result = zend_call_function(&fci, &fcic);
1107
906k
  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
906k
  if (!retval_ptr) {
1116
513k
    zval_ptr_dtor(&retval);
1117
513k
  }
1118
906k
}
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
311
{
1123
311
  zval params[2];
1124
311
  ZVAL_COPY_VALUE(&params[0], param1);
1125
311
  ZVAL_COPY_VALUE(&params[1], param2);
1126
311
  zend_call_known_instance_method(fn, object, retval_ptr, 2, params);
1127
311
}
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
584
{
1133
584
  zend_fcall_info fci;
1134
584
  fci.size = sizeof(zend_fcall_info);
1135
584
  fci.object = object;
1136
584
  ZVAL_STR(&fci.function_name, method_name);
1137
584
  fci.retval = retval;
1138
584
  fci.param_count = param_count;
1139
584
  fci.params = params;
1140
584
  fci.named_params = NULL;
1141
1142
584
  zend_fcall_info_cache fcc;
1143
584
  if (!zend_is_callable_ex(&fci.function_name, fci.object, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fcc, NULL)) {
1144
168
    ZVAL_UNDEF(retval);
1145
168
    return FAILURE;
1146
168
  }
1147
1148
416
  return zend_call_function(&fci, &fcc);
1149
584
}
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
218k
ZEND_API bool zend_is_valid_class_name(zend_string *name) {
1164
2.16M
  for (size_t i = 0; i < ZSTR_LEN(name); i++) {
1165
1.95M
    unsigned char c = ZSTR_VAL(name)[i];
1166
1.95M
    if (!ZEND_BIT_TEST(valid_chars, c)) {
1167
3.47k
      return 0;
1168
3.47k
    }
1169
1.95M
  }
1170
215k
  return 1;
1171
218k
}
1172
1173
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *key, uint32_t flags) /* {{{ */
1174
1.14M
{
1175
1.14M
  zend_class_entry *ce = NULL;
1176
1.14M
  zval *zv;
1177
1.14M
  zend_string *lc_name;
1178
1.14M
  zend_string *autoload_name;
1179
1.14M
  uint32_t ce_cache = 0;
1180
1181
1.14M
  if (ZSTR_HAS_CE_CACHE(name) && ZSTR_VALID_CE_CACHE(name)) {
1182
496k
    ce_cache = GC_REFCOUNT(name);
1183
496k
    ce = GET_CE_CACHE(ce_cache);
1184
496k
    if (EXPECTED(ce)) {
1185
235k
      return ce;
1186
235k
    }
1187
496k
  }
1188
1189
910k
  if (key) {
1190
606k
    lc_name = key;
1191
606k
  } else {
1192
303k
    if (!ZSTR_LEN(name)) {
1193
87
      return NULL;
1194
87
    }
1195
1196
303k
    if (ZSTR_VAL(name)[0] == '\\') {
1197
89
      lc_name = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
1198
89
      zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
1199
303k
    } else {
1200
303k
      lc_name = zend_string_tolower(name);
1201
303k
    }
1202
303k
  }
1203
1204
910k
  zv = zend_hash_find(EG(class_table), lc_name);
1205
910k
  if (zv) {
1206
108k
    if (!key) {
1207
29.4k
      zend_string_release_ex(lc_name, 0);
1208
29.4k
    }
1209
108k
    ce = (zend_class_entry*)Z_PTR_P(zv);
1210
108k
    if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_LINKED))) {
1211
3.89k
      if ((flags & ZEND_FETCH_CLASS_ALLOW_UNLINKED) ||
1212
3.89k
        ((flags & ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED) &&
1213
3.85k
          (ce->ce_flags & ZEND_ACC_NEARLY_LINKED))) {
1214
3.85k
        if (!CG(unlinked_uses)) {
1215
229
          ALLOC_HASHTABLE(CG(unlinked_uses));
1216
229
          zend_hash_init(CG(unlinked_uses), 0, NULL, NULL, 0);
1217
229
        }
1218
3.85k
        zend_hash_index_add_empty_element(CG(unlinked_uses), (zend_long)(uintptr_t)ce);
1219
3.85k
        return ce;
1220
3.85k
      }
1221
39
      return NULL;
1222
3.89k
    }
1223
    /* Don't populate CE_CACHE for mutable classes during compilation.
1224
     * The class may be freed while persisting. */
1225
104k
    if (ce_cache &&
1226
104k
        (!CG(in_compilation) || (ce->ce_flags & ZEND_ACC_IMMUTABLE))) {
1227
70.4k
      SET_CE_CACHE(ce_cache, ce);
1228
70.4k
    }
1229
104k
    return ce;
1230
108k
  }
1231
1232
  /* The compiler is not-reentrant. Make sure we autoload only during run-time. */
1233
802k
  if ((flags & ZEND_FETCH_CLASS_NO_AUTOLOAD) || zend_is_compiling()) {
1234
580k
    if (!key) {
1235
269k
      zend_string_release_ex(lc_name, 0);
1236
269k
    }
1237
580k
    return NULL;
1238
580k
  }
1239
1240
221k
  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
221k
  if (!key && !ZSTR_HAS_CE_CACHE(name) && !zend_is_valid_class_name(name)) {
1249
3.23k
    zend_string_release_ex(lc_name, 0);
1250
3.23k
    return NULL;
1251
3.23k
  }
1252
1253
218k
  if (EG(in_autoload) == NULL) {
1254
6.92k
    ALLOC_HASHTABLE(EG(in_autoload));
1255
6.92k
    zend_hash_init(EG(in_autoload), 8, NULL, NULL, 0);
1256
6.92k
  }
1257
1258
218k
  if (zend_hash_add_empty_element(EG(in_autoload), lc_name) == NULL) {
1259
16
    if (!key) {
1260
7
      zend_string_release_ex(lc_name, 0);
1261
7
    }
1262
16
    return NULL;
1263
16
  }
1264
1265
218k
  if (ZSTR_VAL(name)[0] == '\\') {
1266
45
    autoload_name = zend_string_init(ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1, 0);
1267
218k
  } else {
1268
218k
    autoload_name = zend_string_copy(name);
1269
218k
  }
1270
1271
218k
  zend_string *previous_filename = EG(filename_override);
1272
218k
  zend_long previous_lineno = EG(lineno_override);
1273
218k
  EG(filename_override) = NULL;
1274
218k
  EG(lineno_override) = -1;
1275
218k
  zend_exception_save();
1276
218k
  ce = zend_autoload(autoload_name, lc_name);
1277
218k
  zend_exception_restore();
1278
218k
  EG(filename_override) = previous_filename;
1279
218k
  EG(lineno_override) = previous_lineno;
1280
1281
218k
  zend_string_release_ex(autoload_name, 0);
1282
218k
  zend_hash_del(EG(in_autoload), lc_name);
1283
1284
218k
  if (!key) {
1285
1.34k
    zend_string_release_ex(lc_name, 0);
1286
1.34k
  }
1287
218k
  if (ce) {
1288
494
    ZEND_ASSERT(!CG(in_compilation));
1289
494
    if (ce_cache) {
1290
383
      SET_CE_CACHE(ce_cache, ce);
1291
383
    }
1292
494
  }
1293
218k
  return ce;
1294
218k
}
1295
/* }}} */
1296
1297
ZEND_API zend_class_entry *zend_lookup_class(zend_string *name) /* {{{ */
1298
12.2k
{
1299
12.2k
  return zend_lookup_class_ex(name, NULL, 0);
1300
12.2k
}
1301
/* }}} */
1302
1303
ZEND_API zend_class_entry *zend_get_called_scope(zend_execute_data *ex) /* {{{ */
1304
89.9k
{
1305
89.9k
  while (ex) {
1306
3.00k
    if (Z_TYPE(ex->This) == IS_OBJECT) {
1307
1.60k
      return Z_OBJCE(ex->This);
1308
1.60k
    } else if (Z_CE(ex->This)) {
1309
887
      return Z_CE(ex->This);
1310
887
    } else if (ex->func) {
1311
516
      if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
1312
464
        return NULL;
1313
464
      }
1314
516
    }
1315
52
    ex = ex->prev_execute_data;
1316
52
  }
1317
86.9k
  return NULL;
1318
89.9k
}
1319
/* }}} */
1320
1321
ZEND_API zend_object *zend_get_this_object(zend_execute_data *ex) /* {{{ */
1322
89.6k
{
1323
89.6k
  while (ex) {
1324
2.66k
    if (Z_TYPE(ex->This) == IS_OBJECT) {
1325
2.06k
      return Z_OBJ(ex->This);
1326
2.06k
    } else if (ex->func) {
1327
599
      if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
1328
587
        return NULL;
1329
587
      }
1330
599
    }
1331
12
    ex = ex->prev_execute_data;
1332
12
  }
1333
86.9k
  return NULL;
1334
89.6k
}
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), 1);
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, 1);
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), 1);
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
268k
{
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
  zend_max_execution_timer_settime(seconds);
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
268k
    struct itimerval t_r;   /* timeout requested */
1602
268k
    int signo;
1603
1604
    // Prevent EINVAL error
1605
268k
    if (seconds < 0 || seconds > 999999999) {
1606
0
      seconds = 0;
1607
0
    }
1608
1609
268k
    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
268k
    signo = SIGPROF;
1623
268k
# endif
1624
1625
268k
    if (reset_signals) {
1626
268k
# ifdef ZEND_SIGNALS
1627
268k
      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
268k
    }
1645
268k
  }
1646
268k
#endif /* HAVE_SETITIMER */
1647
268k
}
1648
/* }}} */
1649
1650
void zend_set_timeout(zend_long seconds, bool reset_signals) /* {{{ */
1651
268k
{
1652
1653
268k
  EG(timeout_seconds) = seconds;
1654
268k
  zend_set_timeout_ex(seconds, reset_signals);
1655
268k
  zend_atomic_bool_store_ex(&EG(timed_out), false);
1656
268k
}
1657
/* }}} */
1658
1659
void zend_unset_timeout(void) /* {{{ */
1660
268k
{
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
  zend_max_execution_timer_settime(0);
1673
#elif defined(HAVE_SETITIMER)
1674
268k
  if (EG(timeout_seconds)) {
1675
10
    struct itimerval no_timeout;
1676
1677
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;
1678
1679
# if defined(__CYGWIN__) || defined(__PASE__) || (defined(__aarch64__) && defined(__APPLE__))
1680
    setitimer(ITIMER_REAL, &no_timeout, NULL);
1681
# else
1682
10
    setitimer(ITIMER_PROF, &no_timeout, NULL);
1683
10
# endif
1684
10
  }
1685
268k
#endif
1686
268k
  zend_atomic_bool_store_ex(&EG(timed_out), false);
1687
268k
}
1688
/* }}} */
1689
1690
static ZEND_COLD void report_class_fetch_error(zend_string *class_name, uint32_t fetch_type)
1691
313k
{
1692
313k
  if (fetch_type & ZEND_FETCH_CLASS_SILENT) {
1693
311k
    return;
1694
311k
  }
1695
1696
2.31k
  if (EG(exception)) {
1697
226
    if (!(fetch_type & ZEND_FETCH_CLASS_EXCEPTION)) {
1698
0
      zend_exception_uncaught_error("During class fetch");
1699
0
    }
1700
226
    return;
1701
226
  }
1702
1703
2.08k
  if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) {
1704
38
    zend_throw_or_error(fetch_type, NULL, "Interface \"%s\" not found", ZSTR_VAL(class_name));
1705
2.04k
  } else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) {
1706
39
    zend_throw_or_error(fetch_type, NULL, "Trait \"%s\" not found", ZSTR_VAL(class_name));
1707
2.00k
  } else {
1708
2.00k
    zend_throw_or_error(fetch_type, NULL, "Class \"%s\" not found", ZSTR_VAL(class_name));
1709
2.00k
  }
1710
2.08k
}
1711
1712
zend_class_entry *zend_fetch_class(zend_string *class_name, uint32_t fetch_type) /* {{{ */
1713
5.30k
{
1714
5.30k
  zend_class_entry *ce, *scope;
1715
5.30k
  uint32_t fetch_sub_type = fetch_type & ZEND_FETCH_CLASS_MASK;
1716
1717
5.41k
check_fetch_type:
1718
5.41k
  switch (fetch_sub_type) {
1719
1.94k
    case ZEND_FETCH_CLASS_SELF:
1720
1.94k
      scope = zend_get_executed_scope();
1721
1.94k
      if (UNEXPECTED(!scope)) {
1722
46
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"self\" when no class scope is active");
1723
46
      }
1724
1.94k
      return scope;
1725
699
    case ZEND_FETCH_CLASS_PARENT:
1726
699
      scope = zend_get_executed_scope();
1727
699
      if (UNEXPECTED(!scope)) {
1728
15
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when no class scope is active");
1729
15
        return NULL;
1730
15
      }
1731
684
      if (UNEXPECTED(!scope->parent)) {
1732
0
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when current class scope has no parent");
1733
0
      }
1734
684
      return scope->parent;
1735
787
    case ZEND_FETCH_CLASS_STATIC:
1736
787
      ce = zend_get_called_scope(EG(current_execute_data));
1737
787
      if (UNEXPECTED(!ce)) {
1738
33
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"static\" when no class scope is active");
1739
33
        return NULL;
1740
33
      }
1741
754
      return ce;
1742
118
    case ZEND_FETCH_CLASS_AUTO: {
1743
118
        fetch_sub_type = zend_get_class_fetch_type(class_name);
1744
118
        if (UNEXPECTED(fetch_sub_type != ZEND_FETCH_CLASS_DEFAULT)) {
1745
112
          goto check_fetch_type;
1746
112
        }
1747
118
      }
1748
6
      break;
1749
5.41k
  }
1750
1751
1.87k
  ce = zend_lookup_class_ex(class_name, NULL, fetch_type);
1752
1.87k
  if (!ce) {
1753
140
    report_class_fetch_error(class_name, fetch_type);
1754
140
    return NULL;
1755
140
  }
1756
1.73k
  return ce;
1757
1.87k
}
1758
/* }}} */
1759
1760
zend_class_entry *zend_fetch_class_with_scope(
1761
    zend_string *class_name, uint32_t fetch_type, zend_class_entry *scope)
1762
371
{
1763
371
  zend_class_entry *ce;
1764
371
  switch (fetch_type & ZEND_FETCH_CLASS_MASK) {
1765
20
    case ZEND_FETCH_CLASS_SELF:
1766
20
      if (UNEXPECTED(!scope)) {
1767
5
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"self\" when no class scope is active");
1768
5
      }
1769
20
      return scope;
1770
10
    case ZEND_FETCH_CLASS_PARENT:
1771
10
      if (UNEXPECTED(!scope)) {
1772
0
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when no class scope is active");
1773
0
        return NULL;
1774
0
      }
1775
10
      if (UNEXPECTED(!scope->parent)) {
1776
5
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when current class scope has no parent");
1777
5
      }
1778
10
      return scope->parent;
1779
341
    case 0:
1780
341
      break;
1781
    /* Other fetch types are not supported by this function. */
1782
371
    EMPTY_SWITCH_DEFAULT_CASE()
1783
371
  }
1784
1785
341
  ce = zend_lookup_class_ex(class_name, NULL, fetch_type);
1786
341
  if (!ce) {
1787
24
    report_class_fetch_error(class_name, fetch_type);
1788
24
    return NULL;
1789
24
  }
1790
317
  return ce;
1791
341
}
1792
1793
zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *key, uint32_t fetch_type) /* {{{ */
1794
616k
{
1795
616k
  zend_class_entry *ce = zend_lookup_class_ex(class_name, key, fetch_type);
1796
616k
  if (!ce) {
1797
313k
    report_class_fetch_error(class_name, fetch_type);
1798
313k
    return NULL;
1799
313k
  }
1800
303k
  return ce;
1801
616k
}
1802
/* }}} */
1803
1804
ZEND_API zend_result zend_delete_global_variable(zend_string *name) /* {{{ */
1805
0
{
1806
0
  return zend_hash_del_ind(&EG(symbol_table), name);
1807
0
}
1808
/* }}} */
1809
1810
ZEND_API zend_array *zend_rebuild_symbol_table(void) /* {{{ */
1811
7.71k
{
1812
7.71k
  zend_execute_data *ex;
1813
7.71k
  zend_array *symbol_table;
1814
1815
  /* Search for last called user function */
1816
7.71k
  ex = EG(current_execute_data);
1817
7.85k
  while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) {
1818
137
    ex = ex->prev_execute_data;
1819
137
  }
1820
7.71k
  if (!ex) {
1821
0
    return NULL;
1822
0
  }
1823
7.71k
  if (ZEND_CALL_INFO(ex) & ZEND_CALL_HAS_SYMBOL_TABLE) {
1824
58
    return ex->symbol_table;
1825
58
  }
1826
1827
7.65k
  ZEND_ADD_CALL_FLAG(ex, ZEND_CALL_HAS_SYMBOL_TABLE);
1828
7.65k
  if (EG(symtable_cache_ptr) > EG(symtable_cache)) {
1829
715
    symbol_table = ex->symbol_table = *(--EG(symtable_cache_ptr));
1830
715
    if (!ex->func->op_array.last_var) {
1831
87
      return symbol_table;
1832
87
    }
1833
628
    zend_hash_extend(symbol_table, ex->func->op_array.last_var, 0);
1834
6.94k
  } else {
1835
6.94k
    symbol_table = ex->symbol_table = zend_new_array(ex->func->op_array.last_var);
1836
6.94k
    if (!ex->func->op_array.last_var) {
1837
76
      return symbol_table;
1838
76
    }
1839
6.86k
    zend_hash_real_init_mixed(symbol_table);
1840
    /*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
1841
6.86k
  }
1842
7.49k
  if (EXPECTED(ex->func->op_array.last_var)) {
1843
7.49k
    zend_string **str = ex->func->op_array.vars;
1844
7.49k
    zend_string **end = str + ex->func->op_array.last_var;
1845
7.49k
    zval *var = ZEND_CALL_VAR_NUM(ex, 0);
1846
1847
50.3k
    do {
1848
50.3k
      _zend_hash_append_ind(symbol_table, *str, var);
1849
50.3k
      str++;
1850
50.3k
      var++;
1851
50.3k
    } while (str != end);
1852
7.49k
  }
1853
7.49k
  return symbol_table;
1854
7.65k
}
1855
/* }}} */
1856
1857
ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ */
1858
135k
{
1859
135k
  zend_op_array *op_array = &execute_data->func->op_array;
1860
135k
  HashTable *ht = execute_data->symbol_table;
1861
1862
  /* copy real values from symbol table into CV slots and create
1863
     INDIRECT references to CV in symbol table  */
1864
135k
  if (EXPECTED(op_array->last_var)) {
1865
135k
    zend_string **str = op_array->vars;
1866
135k
    zend_string **end = str + op_array->last_var;
1867
135k
    zval *var = EX_VAR_NUM(0);
1868
1869
1.09M
    do {
1870
1.09M
      zval *zv = zend_hash_find_known_hash(ht, *str);
1871
1872
1.09M
      if (zv) {
1873
640k
        if (Z_TYPE_P(zv) == IS_INDIRECT) {
1874
640k
          zval *val = Z_INDIRECT_P(zv);
1875
1876
640k
          ZVAL_COPY_VALUE(var, val);
1877
640k
        } else {
1878
101
          ZVAL_COPY_VALUE(var, zv);
1879
101
        }
1880
640k
      } else {
1881
455k
        ZVAL_UNDEF(var);
1882
455k
        zv = zend_hash_add_new(ht, *str, var);
1883
455k
      }
1884
1.09M
      ZVAL_INDIRECT(zv, var);
1885
1.09M
      str++;
1886
1.09M
      var++;
1887
1.09M
    } while (str != end);
1888
135k
  }
1889
135k
}
1890
/* }}} */
1891
1892
ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ */
1893
45.4k
{
1894
45.4k
  zend_op_array *op_array = &execute_data->func->op_array;
1895
45.4k
  HashTable *ht = execute_data->symbol_table;
1896
1897
  /* copy real values from CV slots into symbol table */
1898
45.4k
  if (EXPECTED(op_array->last_var)) {
1899
45.4k
    zend_string **str = op_array->vars;
1900
45.4k
    zend_string **end = str + op_array->last_var;
1901
45.4k
    zval *var = EX_VAR_NUM(0);
1902
1903
276k
    do {
1904
276k
      if (Z_TYPE_P(var) == IS_UNDEF) {
1905
69.9k
        zend_hash_del(ht, *str);
1906
206k
      } else {
1907
206k
        zend_hash_update(ht, *str, var);
1908
206k
        ZVAL_UNDEF(var);
1909
206k
      }
1910
276k
      str++;
1911
276k
      var++;
1912
276k
    } while (str != end);
1913
45.4k
  }
1914
45.4k
}
1915
/* }}} */
1916
1917
ZEND_API zend_result zend_set_local_var(zend_string *name, zval *value, bool force) /* {{{ */
1918
0
{
1919
0
  zend_execute_data *execute_data = EG(current_execute_data);
1920
1921
0
  while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
1922
0
    execute_data = execute_data->prev_execute_data;
1923
0
  }
1924
1925
0
  if (execute_data) {
1926
0
    if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) {
1927
0
      zend_ulong h = zend_string_hash_val(name);
1928
0
      zend_op_array *op_array = &execute_data->func->op_array;
1929
1930
0
      if (EXPECTED(op_array->last_var)) {
1931
0
        zend_string **str = op_array->vars;
1932
0
        zend_string **end = str + op_array->last_var;
1933
1934
0
        do {
1935
0
          if (ZSTR_H(*str) == h &&
1936
0
              zend_string_equal_content(*str, name)) {
1937
0
            zval *var = EX_VAR_NUM(str - op_array->vars);
1938
0
            ZVAL_COPY_VALUE(var, value);
1939
0
            return SUCCESS;
1940
0
          }
1941
0
          str++;
1942
0
        } while (str != end);
1943
0
      }
1944
0
      if (force) {
1945
0
        zend_array *symbol_table = zend_rebuild_symbol_table();
1946
0
        if (symbol_table) {
1947
0
          zend_hash_update(symbol_table, name, value);
1948
0
          return SUCCESS;
1949
0
        }
1950
0
      }
1951
0
    } else {
1952
0
      zend_hash_update_ind(execute_data->symbol_table, name, value);
1953
0
      return SUCCESS;
1954
0
    }
1955
0
  }
1956
0
  return FAILURE;
1957
0
}
1958
/* }}} */
1959
1960
ZEND_API zend_result zend_set_local_var_str(const char *name, size_t len, zval *value, bool force) /* {{{ */
1961
0
{
1962
0
  zend_execute_data *execute_data = EG(current_execute_data);
1963
1964
0
  while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
1965
0
    execute_data = execute_data->prev_execute_data;
1966
0
  }
1967
1968
0
  if (execute_data) {
1969
0
    if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) {
1970
0
      zend_ulong h = zend_hash_func(name, len);
1971
0
      zend_op_array *op_array = &execute_data->func->op_array;
1972
0
      if (EXPECTED(op_array->last_var)) {
1973
0
        zend_string **str = op_array->vars;
1974
0
        zend_string **end = str + op_array->last_var;
1975
1976
0
        do {
1977
0
          if (ZSTR_H(*str) == h &&
1978
0
              zend_string_equals_cstr(*str, name, len)) {
1979
0
            zval *var = EX_VAR_NUM(str - op_array->vars);
1980
0
            zval_ptr_dtor(var);
1981
0
            ZVAL_COPY_VALUE(var, value);
1982
0
            return SUCCESS;
1983
0
          }
1984
0
          str++;
1985
0
        } while (str != end);
1986
0
      }
1987
0
      if (force) {
1988
0
        zend_array *symbol_table = zend_rebuild_symbol_table();
1989
0
        if (symbol_table) {
1990
0
          zend_hash_str_update(symbol_table, name, len, value);
1991
0
          return SUCCESS;
1992
0
        }
1993
0
      }
1994
0
    } else {
1995
0
      zend_hash_str_update_ind(execute_data->symbol_table, name, len, value);
1996
0
      return SUCCESS;
1997
0
    }
1998
0
  }
1999
0
  return FAILURE;
2000
0
}
2001
/* }}} */