This source file includes following definitions.
- zend_get_parameters
- zend_get_parameters_ex
- _zend_get_parameters_array_ex
- zend_copy_parameters_array
- zend_wrong_param_count
- zend_get_type_by_const
- zend_zval_type_name
- zend_wrong_paramers_count_error
- zend_wrong_paramer_type_error
- zend_wrong_paramer_class_error
- zend_wrong_callback_error
- zend_parse_arg_class
- zend_parse_arg_bool_weak
- zend_parse_arg_bool_slow
- zend_parse_arg_long_weak
- zend_parse_arg_long_slow
- zend_parse_arg_long_cap_weak
- zend_parse_arg_long_cap_slow
- zend_parse_arg_double_weak
- zend_parse_arg_double_slow
- zend_parse_arg_str_weak
- zend_parse_arg_str_slow
- zend_parse_arg_impl
- zend_parse_arg
- zend_parse_parameter
- zend_parse_parameters_debug_error
- zend_parse_va_args
- zend_parse_parameters_ex
- zend_parse_parameters
- zend_parse_parameters_throw
- zend_parse_method_parameters
- zend_parse_method_parameters_ex
- _array_init
- zend_merge_properties
- zend_update_class_constants
- object_properties_init
- object_properties_init_ex
- object_properties_load
- _object_and_properties_init
- _object_init_ex
- _object_init
- add_assoc_long_ex
- add_assoc_null_ex
- add_assoc_bool_ex
- add_assoc_resource_ex
- add_assoc_double_ex
- add_assoc_str_ex
- add_assoc_string_ex
- add_assoc_stringl_ex
- add_assoc_zval_ex
- add_index_long
- add_index_null
- add_index_bool
- add_index_resource
- add_index_double
- add_index_str
- add_index_string
- add_index_stringl
- add_index_zval
- add_next_index_long
- add_next_index_null
- add_next_index_bool
- add_next_index_resource
- add_next_index_double
- add_next_index_str
- add_next_index_string
- add_next_index_stringl
- add_next_index_zval
- add_get_assoc_string_ex
- add_get_assoc_stringl_ex
- add_get_index_long
- add_get_index_double
- add_get_index_str
- add_get_index_string
- add_get_index_stringl
- array_set_zval_key
- add_property_long_ex
- add_property_bool_ex
- add_property_null_ex
- add_property_resource_ex
- add_property_double_ex
- add_property_str_ex
- add_property_string_ex
- add_property_stringl_ex
- add_property_zval_ex
- zend_startup_module_ex
- zend_startup_module_zval
- zend_sort_modules
- zend_collect_module_handlers
- zend_startup_modules
- zend_destroy_modules
- zend_register_module_ex
- zend_register_internal_module
- zend_check_magic_method_implementation
- zend_register_functions
- zend_unregister_functions
- zend_startup_module
- zend_get_module_started
- clean_module_class
- clean_module_classes
- module_destructor
- zend_activate_modules
- module_registry_cleanup
- zend_deactivate_modules
- zend_cleanup_internal_classes
- module_registry_unload_temp
- module_registry_unload_temp_wrapper
- exec_done_cb
- zend_post_deactivate_modules
- zend_next_free_module
- do_register_internal_class
- zend_register_internal_class_ex
- zend_class_implements
- zend_register_internal_class
- zend_register_internal_interface
- zend_register_class_alias_ex
- zend_set_hash_symbol
- ZEND_FUNCTION
- zend_disable_function
- display_disabled_class
- zend_disable_class
- zend_is_callable_check_class
- zend_is_callable_check_func
- zend_is_callable_ex
- zend_is_callable
- zend_make_callable
- zend_fcall_info_init
- zend_fcall_info_args_clear
- zend_fcall_info_args_save
- zend_fcall_info_args_restore
- zend_fcall_info_args_ex
- zend_fcall_info_args
- zend_fcall_info_argp
- zend_fcall_info_argv
- zend_fcall_info_argn
- zend_fcall_info_call
- zend_get_module_version
- zend_declare_property_ex
- zend_declare_property
- zend_declare_property_null
- zend_declare_property_bool
- zend_declare_property_long
- zend_declare_property_double
- zend_declare_property_string
- zend_declare_property_stringl
- zend_declare_class_constant
- zend_declare_class_constant_null
- zend_declare_class_constant_long
- zend_declare_class_constant_bool
- zend_declare_class_constant_double
- zend_declare_class_constant_stringl
- zend_declare_class_constant_string
- zend_update_property_ex
- zend_update_property
- zend_update_property_null
- zend_update_property_bool
- zend_update_property_long
- zend_update_property_double
- zend_update_property_str
- zend_update_property_string
- zend_update_property_stringl
- zend_update_static_property
- zend_update_static_property_null
- zend_update_static_property_bool
- zend_update_static_property_long
- zend_update_static_property_double
- zend_update_static_property_string
- zend_update_static_property_stringl
- zend_read_property
- zend_read_static_property
- zend_save_error_handling
- zend_replace_error_handling
- same_zval
- zend_restore_error_handling
- zend_find_alias_name
- zend_resolve_method_name
- zend_get_object_type
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include "zend.h"
25 #include "zend_execute.h"
26 #include "zend_API.h"
27 #include "zend_modules.h"
28 #include "zend_extensions.h"
29 #include "zend_constants.h"
30 #include "zend_exceptions.h"
31 #include "zend_closures.h"
32 #include "zend_inheritance.h"
33
34 #ifdef HAVE_STDARG_H
35 #include <stdarg.h>
36 #endif
37
38
39 ZEND_API HashTable module_registry;
40
41 static zend_module_entry **module_request_startup_handlers;
42 static zend_module_entry **module_request_shutdown_handlers;
43 static zend_module_entry **module_post_deactivate_handlers;
44
45 static zend_class_entry **class_cleanup_handlers;
46
47
48 ZEND_API int zend_get_parameters(int ht, int param_count, ...)
49 {
50 int arg_count;
51 va_list ptr;
52 zval **param, *param_ptr;
53
54 param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
55 arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
56
57 if (param_count>arg_count) {
58 return FAILURE;
59 }
60
61 va_start(ptr, param_count);
62
63 while (param_count-->0) {
64 param = va_arg(ptr, zval **);
65 if (!Z_ISREF_P(param_ptr) && Z_REFCOUNT_P(param_ptr) > 1) {
66 zval new_tmp;
67
68 ZVAL_DUP(&new_tmp, param_ptr);
69 Z_DELREF_P(param_ptr);
70 ZVAL_COPY_VALUE(param_ptr, &new_tmp);
71 }
72 *param = param_ptr;
73 param_ptr++;
74 }
75 va_end(ptr);
76
77 return SUCCESS;
78 }
79
80
81
82
83 ZEND_API int zend_get_parameters_ex(int param_count, ...)
84 {
85 int arg_count;
86 va_list ptr;
87 zval **param, *param_ptr;
88
89 param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
90 arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
91
92 if (param_count>arg_count) {
93 return FAILURE;
94 }
95
96 va_start(ptr, param_count);
97 while (param_count-->0) {
98 param = va_arg(ptr, zval **);
99 *param = param_ptr;
100 param_ptr++;
101 }
102 va_end(ptr);
103
104 return SUCCESS;
105 }
106
107
108 ZEND_API int _zend_get_parameters_array_ex(int param_count, zval *argument_array)
109 {
110 zval *param_ptr;
111 int arg_count;
112
113 param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
114 arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
115
116 if (param_count>arg_count) {
117 return FAILURE;
118 }
119
120 while (param_count-->0) {
121 ZVAL_COPY_VALUE(argument_array, param_ptr);
122 argument_array++;
123 param_ptr++;
124 }
125
126 return SUCCESS;
127 }
128
129
130 ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array)
131 {
132 zval *param_ptr;
133 int arg_count;
134
135 param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
136 arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
137
138 if (param_count>arg_count) {
139 return FAILURE;
140 }
141
142 while (param_count-->0) {
143 if (Z_REFCOUNTED_P(param_ptr)) {
144 Z_ADDREF_P(param_ptr);
145 }
146 zend_hash_next_index_insert_new(Z_ARRVAL_P(argument_array), param_ptr);
147 param_ptr++;
148 }
149
150 return SUCCESS;
151 }
152
153
154 ZEND_API ZEND_COLD void zend_wrong_param_count(void)
155 {
156 const char *space;
157 const char *class_name = get_active_class_name(&space);
158
159 zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name());
160 }
161
162
163
164 ZEND_API char *zend_get_type_by_const(int type)
165 {
166 switch(type) {
167 case IS_FALSE:
168 case IS_TRUE:
169 case _IS_BOOL:
170 return "boolean";
171 case IS_LONG:
172 return "integer";
173 case IS_DOUBLE:
174 return "float";
175 case IS_STRING:
176 return "string";
177 case IS_OBJECT:
178 return "object";
179 case IS_RESOURCE:
180 return "resource";
181 case IS_NULL:
182 return "null";
183 case IS_CALLABLE:
184 return "callable";
185 case IS_ARRAY:
186 return "array";
187 default:
188 return "unknown";
189 }
190 }
191
192
193 ZEND_API char *zend_zval_type_name(const zval *arg)
194 {
195 ZVAL_DEREF(arg);
196 return zend_get_type_by_const(Z_TYPE_P(arg));
197 }
198
199
200 #ifdef FAST_ZPP
201 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args)
202 {
203 zend_function *active_function = EG(current_execute_data)->func;
204 const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
205
206 zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects %s %d parameter%s, %d given",
207 class_name, \
208 class_name[0] ? "::" : "", \
209 ZSTR_VAL(active_function->common.function_name),
210 min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
211 num_args < min_num_args ? min_num_args : max_num_args,
212 (num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
213 num_args);
214 }
215
216
217 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg)
218 {
219 const char *space;
220 const char *class_name = get_active_class_name(&space);
221 static const char * const expected_error[] = {
222 Z_EXPECTED_TYPES(Z_EXPECTED_TYPE_STR)
223 NULL
224 };
225
226 zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
227 class_name, space, get_active_function_name(), num, expected_error[expected_type], zend_zval_type_name(arg));
228 }
229
230
231 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_paramer_class_error(int num, char *name, zval *arg)
232 {
233 const char *space;
234 const char *class_name = get_active_class_name(&space);
235
236 zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
237 class_name, space, get_active_function_name(), num, name, zend_zval_type_name(arg));
238 }
239
240
241 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int severity, int num, char *error)
242 {
243 const char *space;
244 const char *class_name = get_active_class_name(&space);
245
246 if (severity == E_WARNING) {
247 zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid callback, %s",
248 class_name, space, get_active_function_name(), num, error);
249 } else if (severity == E_ERROR) {
250 zend_throw_error(zend_ce_type_error, "%s%s%s() expects parameter %d to be a valid callback, %s",
251 class_name, space, get_active_function_name(), num, error);
252 } else {
253 zend_error(severity, "%s%s%s() expects parameter %d to be a valid callback, %s",
254 class_name, space, get_active_function_name(), num, error);
255 }
256 efree(error);
257 }
258
259
260 ZEND_API int ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null)
261 {
262 zend_class_entry *ce_base = *pce;
263
264 if (check_null && Z_TYPE_P(arg) == IS_NULL) {
265 *pce = NULL;
266 return 1;
267 }
268 convert_to_string_ex(arg);
269 *pce = zend_lookup_class(Z_STR_P(arg));
270 if (ce_base) {
271 if ((!*pce || !instanceof_function(*pce, ce_base))) {
272 const char *space;
273 const char *class_name = get_active_class_name(&space);
274
275 zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a class name derived from %s, '%s' given",
276 class_name, space, get_active_function_name(), num,
277 ZSTR_VAL(ce_base->name), Z_STRVAL_P(arg));
278 *pce = NULL;
279 return 0;
280 }
281 }
282 if (!*pce) {
283 const char *space;
284 const char *class_name = get_active_class_name(&space);
285
286 zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid class name, '%s' given",
287 class_name, space, get_active_function_name(), num,
288 Z_STRVAL_P(arg));
289 return 0;
290 }
291 return 1;
292 }
293
294 #endif
295
296 ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, zend_bool *dest)
297 {
298 if (EXPECTED(Z_TYPE_P(arg) <= IS_STRING)) {
299 *dest = zend_is_true(arg);
300 } else {
301 return 0;
302 }
303 return 1;
304 }
305
306
307 ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_slow(zval *arg, zend_bool *dest)
308 {
309 if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
310 return 0;
311 }
312 return zend_parse_arg_bool_weak(arg, dest);
313 }
314
315
316 ZEND_API int ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest)
317 {
318 if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
319 if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) {
320 return 0;
321 }
322 if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) {
323 return 0;
324 } else {
325 *dest = zend_dval_to_lval(Z_DVAL_P(arg));
326 }
327 } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
328 double d;
329 int type;
330
331 if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) {
332 if (EXPECTED(type != 0)) {
333 if (UNEXPECTED(zend_isnan(d))) {
334 return 0;
335 }
336 if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) {
337 return 0;
338 } else {
339 *dest = zend_dval_to_lval(d);
340 }
341 } else {
342 return 0;
343 }
344 }
345 } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
346 *dest = 0;
347 } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
348 *dest = 1;
349 } else {
350 return 0;
351 }
352 return 1;
353 }
354
355
356 ZEND_API int ZEND_FASTCALL zend_parse_arg_long_slow(zval *arg, zend_long *dest)
357 {
358 if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
359 return 0;
360 }
361 return zend_parse_arg_long_weak(arg, dest);
362 }
363
364
365 ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_weak(zval *arg, zend_long *dest)
366 {
367 if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
368 if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) {
369 return 0;
370 }
371 if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) {
372 *dest = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
373 } else {
374 *dest = zend_dval_to_lval(Z_DVAL_P(arg));
375 }
376 } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
377 double d;
378 int type;
379
380 if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) {
381 if (EXPECTED(type != 0)) {
382 if (UNEXPECTED(zend_isnan(d))) {
383 return 0;
384 }
385 if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) {
386 *dest = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
387 } else {
388 *dest = zend_dval_to_lval(d);
389 }
390 } else {
391 return 0;
392 }
393 }
394 } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
395 *dest = 0;
396 } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
397 *dest = 1;
398 } else {
399 return 0;
400 }
401 return 1;
402 }
403
404
405 ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_slow(zval *arg, zend_long *dest)
406 {
407 if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
408 return 0;
409 }
410 return zend_parse_arg_long_cap_weak(arg, dest);
411 }
412
413
414 ZEND_API int ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest)
415 {
416 if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
417 *dest = (double)Z_LVAL_P(arg);
418 } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
419 zend_long l;
420 int type;
421
422 if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, dest)) != IS_DOUBLE)) {
423 if (EXPECTED(type != 0)) {
424 *dest = (double)(l);
425 } else {
426 return 0;
427 }
428 }
429 } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
430 *dest = 0.0;
431 } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
432 *dest = 1.0;
433 } else {
434 return 0;
435 }
436 return 1;
437 }
438
439
440 ZEND_API int ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest)
441 {
442 if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
443
444 *dest = (double)Z_LVAL_P(arg);
445 } else if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
446 return 0;
447 }
448 return zend_parse_arg_double_weak(arg, dest);
449 }
450
451
452 ZEND_API int ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest)
453 {
454 if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) {
455 convert_to_string(arg);
456 *dest = Z_STR_P(arg);
457 } else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
458 if (Z_OBJ_HANDLER_P(arg, cast_object)) {
459 zval obj;
460 if (Z_OBJ_HANDLER_P(arg, cast_object)(arg, &obj, IS_STRING) == SUCCESS) {
461 zval_ptr_dtor(arg);
462 ZVAL_COPY_VALUE(arg, &obj);
463 *dest = Z_STR_P(arg);
464 return 1;
465 }
466 } else if (Z_OBJ_HANDLER_P(arg, get)) {
467 zval rv;
468 zval *z = Z_OBJ_HANDLER_P(arg, get)(arg, &rv);
469
470 Z_ADDREF_P(z);
471 if (Z_TYPE_P(z) != IS_OBJECT) {
472 zval_dtor(arg);
473 ZVAL_NULL(arg);
474 if (!zend_make_printable_zval(z, arg)) {
475 ZVAL_COPY_VALUE(arg, z);
476 }
477 *dest = Z_STR_P(arg);
478 return 1;
479 }
480 zval_ptr_dtor(z);
481 }
482 return 0;
483 } else {
484 return 0;
485 }
486 return 1;
487 }
488
489
490 ZEND_API int ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest)
491 {
492 if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
493 return 0;
494 }
495 return zend_parse_arg_str_weak(arg, dest);
496 }
497
498
499 static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, const char **spec, char **error, int *severity)
500 {
501 const char *spec_walk = *spec;
502 char c = *spec_walk++;
503 int check_null = 0;
504 zval *real_arg = arg;
505
506
507 ZVAL_DEREF(arg);
508 while (1) {
509 if (*spec_walk == '/') {
510 SEPARATE_ZVAL_NOREF(arg);
511 real_arg = arg;
512 } else if (*spec_walk == '!') {
513 check_null = 1;
514 } else {
515 break;
516 }
517 spec_walk++;
518 }
519
520 switch (c) {
521 case 'l':
522 case 'L':
523 {
524 zend_long *p = va_arg(*va, zend_long *);
525 zend_bool *is_null = NULL;
526
527 if (check_null) {
528 is_null = va_arg(*va, zend_bool *);
529 }
530
531 if (!zend_parse_arg_long(arg, p, is_null, check_null, c == 'L')) {
532 return "integer";
533 }
534 }
535 break;
536
537 case 'd':
538 {
539 double *p = va_arg(*va, double *);
540 zend_bool *is_null = NULL;
541
542 if (check_null) {
543 is_null = va_arg(*va, zend_bool *);
544 }
545
546 if (!zend_parse_arg_double(arg, p, is_null, check_null)) {
547 return "float";
548 }
549 }
550 break;
551
552 case 's':
553 {
554 char **p = va_arg(*va, char **);
555 size_t *pl = va_arg(*va, size_t *);
556 if (!zend_parse_arg_string(arg, p, pl, check_null)) {
557 return "string";
558 }
559 }
560 break;
561
562 case 'p':
563 {
564 char **p = va_arg(*va, char **);
565 size_t *pl = va_arg(*va, size_t *);
566 if (!zend_parse_arg_path(arg, p, pl, check_null)) {
567 return "a valid path";
568 }
569 }
570 break;
571
572 case 'P':
573 {
574 zend_string **str = va_arg(*va, zend_string **);
575 if (!zend_parse_arg_path_str(arg, str, check_null)) {
576 return "a valid path";
577 }
578 }
579 break;
580
581 case 'S':
582 {
583 zend_string **str = va_arg(*va, zend_string **);
584 if (!zend_parse_arg_str(arg, str, check_null)) {
585 return "string";
586 }
587 }
588 break;
589
590 case 'b':
591 {
592 zend_bool *p = va_arg(*va, zend_bool *);
593 zend_bool *is_null = NULL;
594
595 if (check_null) {
596 is_null = va_arg(*va, zend_bool *);
597 }
598
599 if (!zend_parse_arg_bool(arg, p, is_null, check_null)) {
600 return "boolean";
601 }
602 }
603 break;
604
605 case 'r':
606 {
607 zval **p = va_arg(*va, zval **);
608
609 if (!zend_parse_arg_resource(arg, p, check_null)) {
610 return "resource";
611 }
612 }
613 break;
614
615 case 'A':
616 case 'a':
617 {
618 zval **p = va_arg(*va, zval **);
619
620 if (!zend_parse_arg_array(arg, p, check_null, c == 'A')) {
621 return "array";
622 }
623 }
624 break;
625
626 case 'H':
627 case 'h':
628 {
629 HashTable **p = va_arg(*va, HashTable **);
630
631 if (!zend_parse_arg_array_ht(arg, p, check_null, c == 'H')) {
632 return "array";
633 }
634 }
635 break;
636
637 case 'o':
638 {
639 zval **p = va_arg(*va, zval **);
640
641 if (!zend_parse_arg_object(arg, p, NULL, check_null)) {
642 return "object";
643 }
644 }
645 break;
646
647 case 'O':
648 {
649 zval **p = va_arg(*va, zval **);
650 zend_class_entry *ce = va_arg(*va, zend_class_entry *);
651
652 if (!zend_parse_arg_object(arg, p, ce, check_null)) {
653 if (ce) {
654 return ZSTR_VAL(ce->name);
655 } else {
656 return "object";
657 }
658 }
659 }
660 break;
661
662 case 'C':
663 {
664 zend_class_entry *lookup, **pce = va_arg(*va, zend_class_entry **);
665 zend_class_entry *ce_base = *pce;
666
667 if (check_null && Z_TYPE_P(arg) == IS_NULL) {
668 *pce = NULL;
669 break;
670 }
671 convert_to_string_ex(arg);
672 if ((lookup = zend_lookup_class(Z_STR_P(arg))) == NULL) {
673 *pce = NULL;
674 } else {
675 *pce = lookup;
676 }
677 if (ce_base) {
678 if ((!*pce || !instanceof_function(*pce, ce_base))) {
679 zend_spprintf(error, 0, "to be a class name derived from %s, '%s' given",
680 ZSTR_VAL(ce_base->name), Z_STRVAL_P(arg));
681 *pce = NULL;
682 return "";
683 }
684 }
685 if (!*pce) {
686 zend_spprintf(error, 0, "to be a valid class name, '%s' given",
687 Z_STRVAL_P(arg));
688 return "";
689 }
690 break;
691
692 }
693 break;
694
695 case 'f':
696 {
697 zend_fcall_info *fci = va_arg(*va, zend_fcall_info *);
698 zend_fcall_info_cache *fcc = va_arg(*va, zend_fcall_info_cache *);
699 char *is_callable_error = NULL;
700
701 if (check_null && Z_TYPE_P(arg) == IS_NULL) {
702 fci->size = 0;
703 fcc->initialized = 0;
704 break;
705 }
706
707 if (zend_fcall_info_init(arg, 0, fci, fcc, NULL, &is_callable_error) == SUCCESS) {
708 if (is_callable_error) {
709 *severity = E_DEPRECATED;
710 zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error);
711 efree(is_callable_error);
712 *spec = spec_walk;
713 return "";
714 }
715 break;
716 } else {
717 if (is_callable_error) {
718 *severity = E_ERROR;
719 zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error);
720 efree(is_callable_error);
721 return "";
722 } else {
723 return "valid callback";
724 }
725 }
726 }
727
728 case 'z':
729 {
730 zval **p = va_arg(*va, zval **);
731
732 zend_parse_arg_zval_deref(real_arg, p, check_null);
733 }
734 break;
735
736 case 'Z':
737
738 ZEND_ASSERT(c != 'Z');
739 default:
740 return "unknown";
741 }
742
743 *spec = spec_walk;
744
745 return NULL;
746 }
747
748
749 static int zend_parse_arg(int arg_num, zval *arg, va_list *va, const char **spec, int flags)
750 {
751 const char *expected_type = NULL;
752 char *error = NULL;
753 int severity = 0;
754
755 expected_type = zend_parse_arg_impl(arg_num, arg, va, spec, &error, &severity);
756 if (expected_type) {
757 if (!(flags & ZEND_PARSE_PARAMS_QUIET) && (*expected_type || error)) {
758 const char *space;
759 const char *class_name = get_active_class_name(&space);
760 zend_bool throw_exception =
761 ZEND_ARG_USES_STRICT_TYPES() || (flags & ZEND_PARSE_PARAMS_THROW);
762
763 if (error) {
764 zend_internal_type_error(throw_exception, "%s%s%s() expects parameter %d %s",
765 class_name, space, get_active_function_name(), arg_num, error);
766 efree(error);
767 } else {
768 zend_internal_type_error(throw_exception,
769 "%s%s%s() expects parameter %d to be %s, %s given",
770 class_name, space, get_active_function_name(), arg_num, expected_type,
771 zend_zval_type_name(arg));
772 }
773 }
774 if (severity != E_DEPRECATED) {
775 return FAILURE;
776 }
777 }
778
779 return SUCCESS;
780 }
781
782
783 ZEND_API int zend_parse_parameter(int flags, int arg_num, zval *arg, const char *spec, ...)
784 {
785 va_list va;
786 int ret;
787
788 va_start(va, spec);
789 ret = zend_parse_arg(arg_num, arg, &va, &spec, flags);
790 va_end(va);
791
792 return ret;
793 }
794
795 static ZEND_COLD void zend_parse_parameters_debug_error(const char *msg) {
796 zend_function *active_function = EG(current_execute_data)->func;
797 const char *class_name = active_function->common.scope
798 ? ZSTR_VAL(active_function->common.scope->name) : "";
799 zend_error_noreturn(E_CORE_ERROR, "%s%s%s(): %s",
800 class_name, class_name[0] ? "::" : "",
801 ZSTR_VAL(active_function->common.function_name), msg);
802 }
803
804 static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, int flags)
805 {
806 const char *spec_walk;
807 int c, i;
808 int min_num_args = -1;
809 int max_num_args = 0;
810 int post_varargs = 0;
811 zval *arg;
812 int arg_count;
813 zend_bool have_varargs = 0;
814 zval **varargs = NULL;
815 int *n_varargs = NULL;
816
817 for (spec_walk = type_spec; *spec_walk; spec_walk++) {
818 c = *spec_walk;
819 switch (c) {
820 case 'l': case 'd':
821 case 's': case 'b':
822 case 'r': case 'a':
823 case 'o': case 'O':
824 case 'z': case 'Z':
825 case 'C': case 'h':
826 case 'f': case 'A':
827 case 'H': case 'p':
828 case 'S': case 'P':
829 case 'L':
830 max_num_args++;
831 break;
832
833 case '|':
834 min_num_args = max_num_args;
835 break;
836
837 case '/':
838 case '!':
839
840 break;
841
842 case '*':
843 case '+':
844 if (have_varargs) {
845 zend_parse_parameters_debug_error(
846 "only one varargs specifier (* or +) is permitted");
847 return FAILURE;
848 }
849 have_varargs = 1;
850
851 if (c == '+') {
852 max_num_args++;
853 }
854
855 post_varargs = max_num_args;
856 break;
857
858 default:
859 zend_parse_parameters_debug_error("bad type specifier while parsing parameters");
860 return FAILURE;
861 }
862 }
863
864 if (min_num_args < 0) {
865 min_num_args = max_num_args;
866 }
867
868 if (have_varargs) {
869
870 post_varargs = max_num_args - post_varargs;
871 max_num_args = -1;
872 }
873
874 if (num_args < min_num_args || (num_args > max_num_args && max_num_args >= 0)) {
875 if (!(flags & ZEND_PARSE_PARAMS_QUIET)) {
876 zend_function *active_function = EG(current_execute_data)->func;
877 const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
878 zend_bool throw_exception = ZEND_ARG_USES_STRICT_TYPES() || (flags & ZEND_PARSE_PARAMS_THROW);
879 zend_internal_type_error(throw_exception, "%s%s%s() expects %s %d parameter%s, %d given",
880 class_name,
881 class_name[0] ? "::" : "",
882 ZSTR_VAL(active_function->common.function_name),
883 min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
884 num_args < min_num_args ? min_num_args : max_num_args,
885 (num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
886 num_args);
887 }
888 return FAILURE;
889 }
890
891 arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
892
893 if (num_args > arg_count) {
894 zend_parse_parameters_debug_error("could not obtain parameters for parsing");
895 return FAILURE;
896 }
897
898 i = 0;
899 while (num_args-- > 0) {
900 if (*type_spec == '|') {
901 type_spec++;
902 }
903
904 if (*type_spec == '*' || *type_spec == '+') {
905 int num_varargs = num_args + 1 - post_varargs;
906
907
908 varargs = va_arg(*va, zval **);
909 n_varargs = va_arg(*va, int *);
910 type_spec++;
911
912 if (num_varargs > 0) {
913 *n_varargs = num_varargs;
914 *varargs = ZEND_CALL_ARG(EG(current_execute_data), i + 1);
915
916 num_args += 1 - num_varargs;
917 i += num_varargs;
918 continue;
919 } else {
920 *varargs = NULL;
921 *n_varargs = 0;
922 }
923 }
924
925 arg = ZEND_CALL_ARG(EG(current_execute_data), i + 1);
926
927 if (zend_parse_arg(i+1, arg, va, &type_spec, flags) == FAILURE) {
928
929 if (varargs && *varargs) {
930 *varargs = NULL;
931 }
932 return FAILURE;
933 }
934 i++;
935 }
936
937 return SUCCESS;
938 }
939
940
941 ZEND_API int zend_parse_parameters_ex(int flags, int num_args, const char *type_spec, ...)
942 {
943 va_list va;
944 int retval;
945
946 va_start(va, type_spec);
947 retval = zend_parse_va_args(num_args, type_spec, &va, flags);
948 va_end(va);
949
950 return retval;
951 }
952
953
954 ZEND_API int zend_parse_parameters(int num_args, const char *type_spec, ...)
955 {
956 va_list va;
957 int retval;
958 int flags = 0;
959
960 va_start(va, type_spec);
961 retval = zend_parse_va_args(num_args, type_spec, &va, flags);
962 va_end(va);
963
964 return retval;
965 }
966
967
968 ZEND_API int zend_parse_parameters_throw(int num_args, const char *type_spec, ...)
969 {
970 va_list va;
971 int retval;
972 int flags = ZEND_PARSE_PARAMS_THROW;
973
974 va_start(va, type_spec);
975 retval = zend_parse_va_args(num_args, type_spec, &va, flags);
976 va_end(va);
977
978 return retval;
979 }
980
981
982 ZEND_API int zend_parse_method_parameters(int num_args, zval *this_ptr, const char *type_spec, ...)
983 {
984 va_list va;
985 int retval;
986 int flags = 0;
987 const char *p = type_spec;
988 zval **object;
989 zend_class_entry *ce;
990
991
992
993
994
995 zend_bool is_method = EG(current_execute_data)->func->common.scope != NULL;
996
997 if (!is_method || !this_ptr || Z_TYPE_P(this_ptr) != IS_OBJECT) {
998 va_start(va, type_spec);
999 retval = zend_parse_va_args(num_args, type_spec, &va, flags);
1000 va_end(va);
1001 } else {
1002 p++;
1003
1004 va_start(va, type_spec);
1005
1006 object = va_arg(va, zval **);
1007 ce = va_arg(va, zend_class_entry *);
1008 *object = this_ptr;
1009
1010 if (ce && !instanceof_function(Z_OBJCE_P(this_ptr), ce)) {
1011 zend_error_noreturn(E_CORE_ERROR, "%s::%s() must be derived from %s::%s",
1012 ZSTR_VAL(Z_OBJCE_P(this_ptr)->name), get_active_function_name(), ZSTR_VAL(ce->name), get_active_function_name());
1013 }
1014
1015 retval = zend_parse_va_args(num_args, p, &va, flags);
1016 va_end(va);
1017 }
1018 return retval;
1019 }
1020
1021
1022 ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this_ptr, const char *type_spec, ...)
1023 {
1024 va_list va;
1025 int retval;
1026 const char *p = type_spec;
1027 zval **object;
1028 zend_class_entry *ce;
1029
1030 if (!this_ptr) {
1031 va_start(va, type_spec);
1032 retval = zend_parse_va_args(num_args, type_spec, &va, flags);
1033 va_end(va);
1034 } else {
1035 p++;
1036 va_start(va, type_spec);
1037
1038 object = va_arg(va, zval **);
1039 ce = va_arg(va, zend_class_entry *);
1040 *object = this_ptr;
1041
1042 if (ce && !instanceof_function(Z_OBJCE_P(this_ptr), ce)) {
1043 if (!(flags & ZEND_PARSE_PARAMS_QUIET)) {
1044 zend_error_noreturn(E_CORE_ERROR, "%s::%s() must be derived from %s::%s",
1045 ZSTR_VAL(ce->name), get_active_function_name(), ZSTR_VAL(Z_OBJCE_P(this_ptr)->name), get_active_function_name());
1046 }
1047 va_end(va);
1048 return FAILURE;
1049 }
1050
1051 retval = zend_parse_va_args(num_args, p, &va, flags);
1052 va_end(va);
1053 }
1054 return retval;
1055 }
1056
1057
1058
1059 ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC)
1060 {
1061 ZVAL_NEW_ARR(arg);
1062 _zend_hash_init(Z_ARRVAL_P(arg), size, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);
1063 return SUCCESS;
1064 }
1065
1066
1067
1068
1069 ZEND_API void zend_merge_properties(zval *obj, HashTable *properties)
1070 {
1071 const zend_object_handlers *obj_ht = Z_OBJ_HT_P(obj);
1072 zend_class_entry *old_scope = EG(scope);
1073 zend_string *key;
1074 zval *value;
1075
1076 EG(scope) = Z_OBJCE_P(obj);
1077 ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, value) {
1078 if (key) {
1079 zval member;
1080
1081 ZVAL_STR(&member, key);
1082 obj_ht->write_property(obj, &member, value, NULL);
1083 }
1084 } ZEND_HASH_FOREACH_END();
1085 EG(scope) = old_scope;
1086 }
1087
1088
1089 ZEND_API int zend_update_class_constants(zend_class_entry *class_type)
1090 {
1091 if (!(class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
1092 class_type->ce_flags |= ZEND_ACC_CONSTANTS_UPDATED;
1093
1094 if (class_type->parent) {
1095 if (UNEXPECTED(zend_update_class_constants(class_type->parent) != SUCCESS)) {
1096 return FAILURE;
1097 }
1098 }
1099
1100 if (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count) {
1101
1102 int i;
1103 zval *p;
1104
1105 #if ZTS
1106 CG(static_members_table)[(zend_intptr_t)(class_type->static_members_table)] = emalloc(sizeof(zval) * class_type->default_static_members_count);
1107 #else
1108 class_type->static_members_table = emalloc(sizeof(zval) * class_type->default_static_members_count);
1109 #endif
1110 for (i = 0; i < class_type->default_static_members_count; i++) {
1111 p = &class_type->default_static_members_table[i];
1112 if (Z_ISREF_P(p) &&
1113 class_type->parent &&
1114 i < class_type->parent->default_static_members_count &&
1115 p == &class_type->parent->default_static_members_table[i] &&
1116 Z_TYPE(CE_STATIC_MEMBERS(class_type->parent)[i]) != IS_UNDEF
1117 ) {
1118 zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i];
1119
1120 ZVAL_NEW_REF(q, q);
1121 ZVAL_COPY_VALUE(&CE_STATIC_MEMBERS(class_type)[i], q);
1122 Z_ADDREF_P(q);
1123 } else {
1124 ZVAL_DUP(&CE_STATIC_MEMBERS(class_type)[i], p);
1125 }
1126 }
1127 } else {
1128 zend_class_entry **scope = EG(current_execute_data) ? &EG(scope) : &CG(active_class_entry);
1129 zend_class_entry *old_scope = *scope;
1130 zend_class_entry *ce;
1131 zval *val;
1132 zend_property_info *prop_info;
1133
1134 *scope = class_type;
1135 ZEND_HASH_FOREACH_VAL(&class_type->constants_table, val) {
1136 ZVAL_DEREF(val);
1137 if (Z_CONSTANT_P(val)) {
1138 if (UNEXPECTED(zval_update_constant_ex(val, 1, class_type) != SUCCESS)) {
1139 return FAILURE;
1140 }
1141 }
1142 } ZEND_HASH_FOREACH_END();
1143
1144 ce = class_type;
1145 while (ce) {
1146 ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
1147 if (prop_info->ce == ce) {
1148 if (prop_info->flags & ZEND_ACC_STATIC) {
1149 val = CE_STATIC_MEMBERS(class_type) + prop_info->offset;
1150 } else {
1151 val = (zval*)((char*)class_type->default_properties_table + prop_info->offset - OBJ_PROP_TO_OFFSET(0));
1152 }
1153 ZVAL_DEREF(val);
1154 if (Z_CONSTANT_P(val)) {
1155 *scope = ce;
1156 if (UNEXPECTED(zval_update_constant_ex(val, 1, NULL) != SUCCESS)) {
1157 return FAILURE;
1158 }
1159 }
1160 }
1161 } ZEND_HASH_FOREACH_END();
1162 ce = ce->parent;
1163 }
1164
1165 *scope = old_scope;
1166 }
1167 }
1168 return SUCCESS;
1169 }
1170
1171
1172 ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type)
1173 {
1174 if (class_type->default_properties_count) {
1175 zval *src = class_type->default_properties_table;
1176 zval *dst = object->properties_table;
1177 zval *end = src + class_type->default_properties_count;
1178
1179 do {
1180 #if ZTS
1181 ZVAL_DUP(dst, src);
1182 #else
1183 ZVAL_COPY(dst, src);
1184 #endif
1185 src++;
1186 dst++;
1187 } while (src != end);
1188 object->properties = NULL;
1189 }
1190 }
1191
1192
1193 ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properties)
1194 {
1195 object->properties = properties;
1196 if (object->ce->default_properties_count) {
1197 zval *prop;
1198 zend_string *key;
1199 zend_property_info *property_info;
1200
1201 ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, prop) {
1202 property_info = zend_get_property_info(object->ce, key, 1);
1203 if (property_info != ZEND_WRONG_PROPERTY_INFO &&
1204 property_info &&
1205 (property_info->flags & ZEND_ACC_STATIC) == 0) {
1206 zval *slot = OBJ_PROP(object, property_info->offset);
1207 ZVAL_COPY_VALUE(slot, prop);
1208 ZVAL_INDIRECT(prop, slot);
1209 }
1210 } ZEND_HASH_FOREACH_END();
1211 }
1212 }
1213
1214
1215 ZEND_API void object_properties_load(zend_object *object, HashTable *properties)
1216 {
1217 zval *prop, tmp;
1218 zend_string *key;
1219 zend_long h;
1220 zend_property_info *property_info;
1221
1222 ZEND_HASH_FOREACH_KEY_VAL(properties, h, key, prop) {
1223 if (key) {
1224 if (ZSTR_VAL(key)[0] == '\0') {
1225 const char *class_name, *prop_name;
1226 size_t prop_name_len;
1227 if (zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_name_len) == SUCCESS) {
1228 zend_string *pname = zend_string_init(prop_name, prop_name_len, 0);
1229 zend_class_entry *prev_scope = EG(scope);
1230 if (class_name && class_name[0] != '*') {
1231 zend_string *cname = zend_string_init(class_name, strlen(class_name), 0);
1232 EG(scope) = zend_lookup_class(cname);
1233 zend_string_release(cname);
1234 }
1235 property_info = zend_get_property_info(object->ce, pname, 1);
1236 zend_string_release(pname);
1237 EG(scope) = prev_scope;
1238 } else {
1239 property_info = ZEND_WRONG_PROPERTY_INFO;
1240 }
1241 } else {
1242 property_info = zend_get_property_info(object->ce, key, 1);
1243 }
1244 if (property_info != ZEND_WRONG_PROPERTY_INFO &&
1245 property_info &&
1246 (property_info->flags & ZEND_ACC_STATIC) == 0) {
1247 zval *slot = OBJ_PROP(object, property_info->offset);
1248 zval_ptr_dtor(slot);
1249 ZVAL_COPY_VALUE(slot, prop);
1250 zval_add_ref(slot);
1251 if (object->properties) {
1252 ZVAL_INDIRECT(&tmp, slot);
1253 zend_hash_update(object->properties, key, &tmp);
1254 }
1255 } else {
1256 if (!object->properties) {
1257 rebuild_object_properties(object);
1258 }
1259 prop = zend_hash_update(object->properties, key, prop);
1260 zval_add_ref(prop);
1261 }
1262 } else {
1263 if (!object->properties) {
1264 rebuild_object_properties(object);
1265 }
1266 prop = zend_hash_index_update(object->properties, h, prop);
1267 zval_add_ref(prop);
1268 }
1269 } ZEND_HASH_FOREACH_END();
1270 }
1271
1272
1273
1274
1275
1276
1277 ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC)
1278 {
1279 if (UNEXPECTED(class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
1280 if (class_type->ce_flags & ZEND_ACC_INTERFACE) {
1281 zend_throw_error(NULL, "Cannot instantiate interface %s", ZSTR_VAL(class_type->name));
1282 } else if (class_type->ce_flags & ZEND_ACC_TRAIT) {
1283 zend_throw_error(NULL, "Cannot instantiate trait %s", ZSTR_VAL(class_type->name));
1284 } else {
1285 zend_throw_error(NULL, "Cannot instantiate abstract class %s", ZSTR_VAL(class_type->name));
1286 }
1287 ZVAL_NULL(arg);
1288 Z_OBJ_P(arg) = NULL;
1289 return FAILURE;
1290 }
1291
1292 if (UNEXPECTED(!(class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
1293 if (UNEXPECTED(zend_update_class_constants(class_type) != SUCCESS)) {
1294 ZVAL_NULL(arg);
1295 Z_OBJ_P(arg) = NULL;
1296 return FAILURE;
1297 }
1298 }
1299
1300 if (class_type->create_object == NULL) {
1301 ZVAL_OBJ(arg, zend_objects_new(class_type));
1302 if (properties) {
1303 object_properties_init_ex(Z_OBJ_P(arg), properties);
1304 } else {
1305 object_properties_init(Z_OBJ_P(arg), class_type);
1306 }
1307 } else {
1308 ZVAL_OBJ(arg, class_type->create_object(class_type));
1309 }
1310 return SUCCESS;
1311 }
1312
1313
1314 ZEND_API int _object_init_ex(zval *arg, zend_class_entry *class_type ZEND_FILE_LINE_DC)
1315 {
1316 return _object_and_properties_init(arg, class_type, 0 ZEND_FILE_LINE_RELAY_CC);
1317 }
1318
1319
1320 ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC)
1321 {
1322 return _object_init_ex(arg, zend_standard_class_def ZEND_FILE_LINE_RELAY_CC);
1323 }
1324
1325
1326 ZEND_API int add_assoc_long_ex(zval *arg, const char *key, size_t key_len, zend_long n)
1327 {
1328 zval *ret, tmp;
1329
1330 ZVAL_LONG(&tmp, n);
1331 ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
1332 return ret ? SUCCESS : FAILURE;
1333 }
1334
1335
1336 ZEND_API int add_assoc_null_ex(zval *arg, const char *key, size_t key_len)
1337 {
1338 zval *ret, tmp;
1339
1340 ZVAL_NULL(&tmp);
1341 ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
1342 return ret ? SUCCESS : FAILURE;
1343 }
1344
1345
1346 ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, size_t key_len, int b)
1347 {
1348 zval *ret, tmp;
1349
1350 ZVAL_BOOL(&tmp, b);
1351 ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
1352 return ret ? SUCCESS : FAILURE;
1353 }
1354
1355
1356 ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, size_t key_len, zend_resource *r)
1357 {
1358 zval *ret, tmp;
1359
1360 ZVAL_RES(&tmp, r);
1361 ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
1362 return ret ? SUCCESS : FAILURE;
1363 }
1364
1365
1366 ZEND_API int add_assoc_double_ex(zval *arg, const char *key, size_t key_len, double d)
1367 {
1368 zval *ret, tmp;
1369
1370 ZVAL_DOUBLE(&tmp, d);
1371 ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
1372 return ret ? SUCCESS : FAILURE;
1373 }
1374
1375
1376 ZEND_API int add_assoc_str_ex(zval *arg, const char *key, size_t key_len, zend_string *str)
1377 {
1378 zval *ret, tmp;
1379
1380 ZVAL_STR(&tmp, str);
1381 ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
1382 return ret ? SUCCESS : FAILURE;
1383 }
1384
1385
1386 ZEND_API int add_assoc_string_ex(zval *arg, const char *key, size_t key_len, char *str)
1387 {
1388 zval *ret, tmp;
1389
1390 ZVAL_STRING(&tmp, str);
1391 ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
1392 return ret ? SUCCESS : FAILURE;
1393 }
1394
1395
1396 ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, size_t key_len, char *str, size_t length)
1397 {
1398 zval *ret, tmp;
1399
1400 ZVAL_STRINGL(&tmp, str, length);
1401 ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
1402 return ret ? SUCCESS : FAILURE;
1403 }
1404
1405
1406 ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, size_t key_len, zval *value)
1407 {
1408 zval *ret;
1409
1410 ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, value);
1411 return ret ? SUCCESS : FAILURE;
1412 }
1413
1414
1415 ZEND_API int add_index_long(zval *arg, zend_ulong index, zend_long n)
1416 {
1417 zval tmp;
1418
1419 ZVAL_LONG(&tmp, n);
1420 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
1421 }
1422
1423
1424 ZEND_API int add_index_null(zval *arg, zend_ulong index)
1425 {
1426 zval tmp;
1427
1428 ZVAL_NULL(&tmp);
1429 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
1430 }
1431
1432
1433 ZEND_API int add_index_bool(zval *arg, zend_ulong index, int b)
1434 {
1435 zval tmp;
1436
1437 ZVAL_BOOL(&tmp, b);
1438 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
1439 }
1440
1441
1442 ZEND_API int add_index_resource(zval *arg, zend_ulong index, zend_resource *r)
1443 {
1444 zval tmp;
1445
1446 ZVAL_RES(&tmp, r);
1447 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
1448 }
1449
1450
1451 ZEND_API int add_index_double(zval *arg, zend_ulong index, double d)
1452 {
1453 zval tmp;
1454
1455 ZVAL_DOUBLE(&tmp, d);
1456 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
1457 }
1458
1459
1460 ZEND_API int add_index_str(zval *arg, zend_ulong index, zend_string *str)
1461 {
1462 zval tmp;
1463
1464 ZVAL_STR(&tmp, str);
1465 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
1466 }
1467
1468
1469 ZEND_API int add_index_string(zval *arg, zend_ulong index, const char *str)
1470 {
1471 zval tmp;
1472
1473 ZVAL_STRING(&tmp, str);
1474 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
1475 }
1476
1477
1478 ZEND_API int add_index_stringl(zval *arg, zend_ulong index, const char *str, size_t length)
1479 {
1480 zval tmp;
1481
1482 ZVAL_STRINGL(&tmp, str, length);
1483 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
1484 }
1485
1486
1487 ZEND_API int add_index_zval(zval *arg, zend_ulong index, zval *value)
1488 {
1489 return zend_hash_index_update(Z_ARRVAL_P(arg), index, value) ? SUCCESS : FAILURE;
1490 }
1491
1492
1493 ZEND_API int add_next_index_long(zval *arg, zend_long n)
1494 {
1495 zval tmp;
1496
1497 ZVAL_LONG(&tmp, n);
1498 return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
1499 }
1500
1501
1502 ZEND_API int add_next_index_null(zval *arg)
1503 {
1504 zval tmp;
1505
1506 ZVAL_NULL(&tmp);
1507 return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
1508 }
1509
1510
1511 ZEND_API int add_next_index_bool(zval *arg, int b)
1512 {
1513 zval tmp;
1514
1515 ZVAL_BOOL(&tmp, b);
1516 return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
1517 }
1518
1519
1520 ZEND_API int add_next_index_resource(zval *arg, zend_resource *r)
1521 {
1522 zval tmp;
1523
1524 ZVAL_RES(&tmp, r);
1525 return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
1526 }
1527
1528
1529 ZEND_API int add_next_index_double(zval *arg, double d)
1530 {
1531 zval tmp;
1532
1533 ZVAL_DOUBLE(&tmp, d);
1534 return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
1535 }
1536
1537
1538 ZEND_API int add_next_index_str(zval *arg, zend_string *str)
1539 {
1540 zval tmp;
1541
1542 ZVAL_STR(&tmp, str);
1543 return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
1544 }
1545
1546
1547 ZEND_API int add_next_index_string(zval *arg, const char *str)
1548 {
1549 zval tmp;
1550
1551 ZVAL_STRING(&tmp, str);
1552 return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
1553 }
1554
1555
1556 ZEND_API int add_next_index_stringl(zval *arg, const char *str, size_t length)
1557 {
1558 zval tmp;
1559
1560 ZVAL_STRINGL(&tmp, str, length);
1561 return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
1562 }
1563
1564
1565 ZEND_API int add_next_index_zval(zval *arg, zval *value)
1566 {
1567 return zend_hash_next_index_insert(Z_ARRVAL_P(arg), value) ? SUCCESS : FAILURE;
1568 }
1569
1570
1571 ZEND_API zval *add_get_assoc_string_ex(zval *arg, const char *key, uint key_len, const char *str)
1572 {
1573 zval tmp, *ret;
1574
1575 ZVAL_STRING(&tmp, str);
1576 ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
1577 return ret;
1578 }
1579
1580
1581 ZEND_API zval *add_get_assoc_stringl_ex(zval *arg, const char *key, uint key_len, const char *str, size_t length)
1582 {
1583 zval tmp, *ret;
1584
1585 ZVAL_STRINGL(&tmp, str, length);
1586 ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
1587 return ret;
1588 }
1589
1590
1591 ZEND_API zval *add_get_index_long(zval *arg, zend_ulong index, zend_long l)
1592 {
1593 zval tmp;
1594
1595 ZVAL_LONG(&tmp, l);
1596 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
1597 }
1598
1599
1600 ZEND_API zval *add_get_index_double(zval *arg, zend_ulong index, double d)
1601 {
1602 zval tmp;
1603
1604 ZVAL_DOUBLE(&tmp, d);
1605 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
1606 }
1607
1608
1609 ZEND_API zval *add_get_index_str(zval *arg, zend_ulong index, zend_string *str)
1610 {
1611 zval tmp;
1612
1613 ZVAL_STR(&tmp, str);
1614 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
1615 }
1616
1617
1618 ZEND_API zval *add_get_index_string(zval *arg, zend_ulong index, const char *str)
1619 {
1620 zval tmp;
1621
1622 ZVAL_STRING(&tmp, str);
1623 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
1624 }
1625
1626
1627 ZEND_API zval *add_get_index_stringl(zval *arg, zend_ulong index, const char *str, size_t length)
1628 {
1629 zval tmp;
1630
1631 ZVAL_STRINGL(&tmp, str, length);
1632 return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
1633 }
1634
1635
1636 ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value)
1637 {
1638 zval *result;
1639
1640 switch (Z_TYPE_P(key)) {
1641 case IS_STRING:
1642 result = zend_symtable_update(ht, Z_STR_P(key), value);
1643 break;
1644 case IS_NULL:
1645 result = zend_symtable_update(ht, ZSTR_EMPTY_ALLOC(), value);
1646 break;
1647 case IS_RESOURCE:
1648 zend_error(E_NOTICE, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_HANDLE_P(key), Z_RES_HANDLE_P(key));
1649 result = zend_hash_index_update(ht, Z_RES_HANDLE_P(key), value);
1650 break;
1651 case IS_FALSE:
1652 result = zend_hash_index_update(ht, 0, value);
1653 break;
1654 case IS_TRUE:
1655 result = zend_hash_index_update(ht, 1, value);
1656 break;
1657 case IS_LONG:
1658 result = zend_hash_index_update(ht, Z_LVAL_P(key), value);
1659 break;
1660 case IS_DOUBLE:
1661 result = zend_hash_index_update(ht, zend_dval_to_lval(Z_DVAL_P(key)), value);
1662 break;
1663 default:
1664 zend_error(E_WARNING, "Illegal offset type");
1665 result = NULL;
1666 }
1667
1668 if (result) {
1669 if (Z_REFCOUNTED_P(result)) {
1670 Z_ADDREF_P(result);
1671 }
1672 return SUCCESS;
1673 } else {
1674 return FAILURE;
1675 }
1676 }
1677
1678
1679 ZEND_API int add_property_long_ex(zval *arg, const char *key, size_t key_len, zend_long n)
1680 {
1681 zval tmp;
1682 zval z_key;
1683
1684 ZVAL_LONG(&tmp, n);
1685 ZVAL_STRINGL(&z_key, key, key_len);
1686 Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
1687 zval_ptr_dtor(&tmp);
1688 zval_ptr_dtor(&z_key);
1689 return SUCCESS;
1690 }
1691
1692
1693 ZEND_API int add_property_bool_ex(zval *arg, const char *key, size_t key_len, zend_long b)
1694 {
1695 zval tmp;
1696 zval z_key;
1697
1698 ZVAL_BOOL(&tmp, b);
1699 ZVAL_STRINGL(&z_key, key, key_len);
1700 Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
1701 zval_ptr_dtor(&tmp);
1702 zval_ptr_dtor(&z_key);
1703 return SUCCESS;
1704 }
1705
1706
1707 ZEND_API int add_property_null_ex(zval *arg, const char *key, size_t key_len)
1708 {
1709 zval tmp;
1710 zval z_key;
1711
1712 ZVAL_NULL(&tmp);
1713 ZVAL_STRINGL(&z_key, key, key_len);
1714 Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
1715 zval_ptr_dtor(&tmp);
1716 zval_ptr_dtor(&z_key);
1717 return SUCCESS;
1718 }
1719
1720
1721 ZEND_API int add_property_resource_ex(zval *arg, const char *key, size_t key_len, zend_resource *r)
1722 {
1723 zval tmp;
1724 zval z_key;
1725
1726 ZVAL_RES(&tmp, r);
1727 ZVAL_STRINGL(&z_key, key, key_len);
1728 Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
1729 zval_ptr_dtor(&tmp);
1730 zval_ptr_dtor(&z_key);
1731 return SUCCESS;
1732 }
1733
1734
1735 ZEND_API int add_property_double_ex(zval *arg, const char *key, size_t key_len, double d)
1736 {
1737 zval tmp;
1738 zval z_key;
1739
1740 ZVAL_DOUBLE(&tmp, d);
1741 ZVAL_STRINGL(&z_key, key, key_len);
1742 Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
1743 zval_ptr_dtor(&tmp);
1744 zval_ptr_dtor(&z_key);
1745 return SUCCESS;
1746 }
1747
1748
1749 ZEND_API int add_property_str_ex(zval *arg, const char *key, size_t key_len, zend_string *str)
1750 {
1751 zval tmp;
1752 zval z_key;
1753
1754 ZVAL_STR(&tmp, str);
1755 ZVAL_STRINGL(&z_key, key, key_len);
1756 Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
1757 zval_ptr_dtor(&tmp);
1758 zval_ptr_dtor(&z_key);
1759 return SUCCESS;
1760 }
1761
1762
1763 ZEND_API int add_property_string_ex(zval *arg, const char *key, size_t key_len, const char *str)
1764 {
1765 zval tmp;
1766 zval z_key;
1767
1768 ZVAL_STRING(&tmp, str);
1769 ZVAL_STRINGL(&z_key, key, key_len);
1770 Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
1771 zval_ptr_dtor(&tmp);
1772 zval_ptr_dtor(&z_key);
1773 return SUCCESS;
1774 }
1775
1776
1777 ZEND_API int add_property_stringl_ex(zval *arg, const char *key, size_t key_len, const char *str, size_t length)
1778 {
1779 zval tmp;
1780 zval z_key;
1781
1782 ZVAL_STRINGL(&tmp, str, length);
1783 ZVAL_STRINGL(&z_key, key, key_len);
1784 Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
1785 zval_ptr_dtor(&tmp);
1786 zval_ptr_dtor(&z_key);
1787 return SUCCESS;
1788 }
1789
1790
1791 ZEND_API int add_property_zval_ex(zval *arg, const char *key, size_t key_len, zval *value)
1792 {
1793 zval z_key;
1794
1795 ZVAL_STRINGL(&z_key, key, key_len);
1796 Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, value, NULL);
1797 zval_ptr_dtor(&z_key);
1798 return SUCCESS;
1799 }
1800
1801
1802 ZEND_API int zend_startup_module_ex(zend_module_entry *module)
1803 {
1804 size_t name_len;
1805 zend_string *lcname;
1806
1807 if (module->module_started) {
1808 return SUCCESS;
1809 }
1810 module->module_started = 1;
1811
1812
1813 if (module->deps) {
1814 const zend_module_dep *dep = module->deps;
1815
1816 while (dep->name) {
1817 if (dep->type == MODULE_DEP_REQUIRED) {
1818 zend_module_entry *req_mod;
1819
1820 name_len = strlen(dep->name);
1821 lcname = zend_string_alloc(name_len, 0);
1822 zend_str_tolower_copy(ZSTR_VAL(lcname), dep->name, name_len);
1823
1824 if ((req_mod = zend_hash_find_ptr(&module_registry, lcname)) == NULL || !req_mod->module_started) {
1825 zend_string_free(lcname);
1826
1827 zend_error(E_CORE_WARNING, "Cannot load module '%s' because required module '%s' is not loaded", module->name, dep->name);
1828 module->module_started = 0;
1829 return FAILURE;
1830 }
1831 zend_string_free(lcname);
1832 }
1833 ++dep;
1834 }
1835 }
1836
1837
1838 if (module->globals_size) {
1839 #ifdef ZTS
1840 ts_allocate_id(module->globals_id_ptr, module->globals_size, (ts_allocate_ctor) module->globals_ctor, (ts_allocate_dtor) module->globals_dtor);
1841 #else
1842 if (module->globals_ctor) {
1843 module->globals_ctor(module->globals_ptr);
1844 }
1845 #endif
1846 }
1847 if (module->module_startup_func) {
1848 EG(current_module) = module;
1849 if (module->module_startup_func(module->type, module->module_number)==FAILURE) {
1850 zend_error_noreturn(E_CORE_ERROR,"Unable to start %s module", module->name);
1851 EG(current_module) = NULL;
1852 return FAILURE;
1853 }
1854 EG(current_module) = NULL;
1855 }
1856 return SUCCESS;
1857 }
1858
1859
1860 static int zend_startup_module_zval(zval *zv)
1861 {
1862 zend_module_entry *module = Z_PTR_P(zv);
1863
1864 return zend_startup_module_ex(module);
1865 }
1866
1867
1868 static void zend_sort_modules(void *base, size_t count, size_t siz, compare_func_t compare, swap_func_t swp)
1869 {
1870 Bucket *b1 = base;
1871 Bucket *b2;
1872 Bucket *end = b1 + count;
1873 Bucket tmp;
1874 zend_module_entry *m, *r;
1875
1876 while (b1 < end) {
1877 try_again:
1878 m = (zend_module_entry*)Z_PTR(b1->val);
1879 if (!m->module_started && m->deps) {
1880 const zend_module_dep *dep = m->deps;
1881 while (dep->name) {
1882 if (dep->type == MODULE_DEP_REQUIRED || dep->type == MODULE_DEP_OPTIONAL) {
1883 b2 = b1 + 1;
1884 while (b2 < end) {
1885 r = (zend_module_entry*)Z_PTR(b2->val);
1886 if (strcasecmp(dep->name, r->name) == 0) {
1887 tmp = *b1;
1888 *b1 = *b2;
1889 *b2 = tmp;
1890 goto try_again;
1891 }
1892 b2++;
1893 }
1894 }
1895 dep++;
1896 }
1897 }
1898 b1++;
1899 }
1900 }
1901
1902
1903 ZEND_API void zend_collect_module_handlers(void)
1904 {
1905 zend_module_entry *module;
1906 int startup_count = 0;
1907 int shutdown_count = 0;
1908 int post_deactivate_count = 0;
1909 zend_class_entry *ce;
1910 int class_count = 0;
1911
1912
1913 ZEND_HASH_FOREACH_PTR(&module_registry, module) {
1914 if (module->request_startup_func) {
1915 startup_count++;
1916 }
1917 if (module->request_shutdown_func) {
1918 shutdown_count++;
1919 }
1920 if (module->post_deactivate_func) {
1921 post_deactivate_count++;
1922 }
1923 } ZEND_HASH_FOREACH_END();
1924 module_request_startup_handlers = (zend_module_entry**)malloc(
1925 sizeof(zend_module_entry*) *
1926 (startup_count + 1 +
1927 shutdown_count + 1 +
1928 post_deactivate_count + 1));
1929 module_request_startup_handlers[startup_count] = NULL;
1930 module_request_shutdown_handlers = module_request_startup_handlers + startup_count + 1;
1931 module_request_shutdown_handlers[shutdown_count] = NULL;
1932 module_post_deactivate_handlers = module_request_shutdown_handlers + shutdown_count + 1;
1933 module_post_deactivate_handlers[post_deactivate_count] = NULL;
1934 startup_count = 0;
1935
1936 ZEND_HASH_FOREACH_PTR(&module_registry, module) {
1937 if (module->request_startup_func) {
1938 module_request_startup_handlers[startup_count++] = module;
1939 }
1940 if (module->request_shutdown_func) {
1941 module_request_shutdown_handlers[--shutdown_count] = module;
1942 }
1943 if (module->post_deactivate_func) {
1944 module_post_deactivate_handlers[--post_deactivate_count] = module;
1945 }
1946 } ZEND_HASH_FOREACH_END();
1947
1948
1949 ZEND_HASH_FOREACH_PTR(CG(class_table), ce) {
1950 if (ce->type == ZEND_INTERNAL_CLASS &&
1951 ce->default_static_members_count > 0) {
1952 class_count++;
1953 }
1954 } ZEND_HASH_FOREACH_END();
1955
1956 class_cleanup_handlers = (zend_class_entry**)malloc(
1957 sizeof(zend_class_entry*) *
1958 (class_count + 1));
1959 class_cleanup_handlers[class_count] = NULL;
1960
1961 if (class_count) {
1962 ZEND_HASH_FOREACH_PTR(CG(class_table), ce) {
1963 if (ce->type == ZEND_INTERNAL_CLASS &&
1964 ce->default_static_members_count > 0) {
1965 class_cleanup_handlers[--class_count] = ce;
1966 }
1967 } ZEND_HASH_FOREACH_END();
1968 }
1969 }
1970
1971
1972 ZEND_API int zend_startup_modules(void)
1973 {
1974 zend_hash_sort_ex(&module_registry, zend_sort_modules, NULL, 0);
1975 zend_hash_apply(&module_registry, zend_startup_module_zval);
1976 return SUCCESS;
1977 }
1978
1979
1980 ZEND_API void zend_destroy_modules(void)
1981 {
1982 free(class_cleanup_handlers);
1983 free(module_request_startup_handlers);
1984 zend_hash_graceful_reverse_destroy(&module_registry);
1985 }
1986
1987
1988 ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module)
1989 {
1990 size_t name_len;
1991 zend_string *lcname;
1992 zend_module_entry *module_ptr;
1993
1994 if (!module) {
1995 return NULL;
1996 }
1997
1998 #if 0
1999 zend_printf("%s: Registering module %d\n", module->name, module->module_number);
2000 #endif
2001
2002
2003 if (module->deps) {
2004 const zend_module_dep *dep = module->deps;
2005
2006 while (dep->name) {
2007 if (dep->type == MODULE_DEP_CONFLICTS) {
2008 name_len = strlen(dep->name);
2009 lcname = zend_string_alloc(name_len, 0);
2010 zend_str_tolower_copy(ZSTR_VAL(lcname), dep->name, name_len);
2011
2012 if (zend_hash_exists(&module_registry, lcname) || zend_get_extension(dep->name)) {
2013 zend_string_free(lcname);
2014
2015 zend_error(E_CORE_WARNING, "Cannot load module '%s' because conflicting module '%s' is already loaded", module->name, dep->name);
2016 return NULL;
2017 }
2018 zend_string_free(lcname);
2019 }
2020 ++dep;
2021 }
2022 }
2023
2024 name_len = strlen(module->name);
2025 lcname = zend_string_alloc(name_len, 1);
2026 zend_str_tolower_copy(ZSTR_VAL(lcname), module->name, name_len);
2027
2028 if ((module_ptr = zend_hash_add_mem(&module_registry, lcname, module, sizeof(zend_module_entry))) == NULL) {
2029 zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name);
2030 zend_string_release(lcname);
2031 return NULL;
2032 }
2033 zend_string_release(lcname);
2034 module = module_ptr;
2035 EG(current_module) = module;
2036
2037 if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type)==FAILURE) {
2038 EG(current_module) = NULL;
2039 zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name);
2040 return NULL;
2041 }
2042
2043 EG(current_module) = NULL;
2044 return module;
2045 }
2046
2047
2048 ZEND_API zend_module_entry* zend_register_internal_module(zend_module_entry *module)
2049 {
2050 module->module_number = zend_next_free_module();
2051 module->type = MODULE_PERSISTENT;
2052 return zend_register_module_ex(module);
2053 }
2054
2055
2056 ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, int error_type)
2057 {
2058 char lcname[16];
2059 size_t name_len;
2060
2061
2062
2063 name_len = ZSTR_LEN(fptr->common.function_name);
2064 zend_str_tolower_copy(lcname, ZSTR_VAL(fptr->common.function_name), MIN(name_len, sizeof(lcname)-1));
2065 lcname[sizeof(lcname)-1] = '\0';
2066
2067 if (name_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1) && fptr->common.num_args != 0) {
2068 zend_error(error_type, "Destructor %s::%s() cannot take arguments", ZSTR_VAL(ce->name), ZEND_DESTRUCTOR_FUNC_NAME);
2069 } else if (name_len == sizeof(ZEND_CLONE_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME) - 1) && fptr->common.num_args != 0) {
2070 zend_error(error_type, "Method %s::%s() cannot accept any arguments", ZSTR_VAL(ce->name), ZEND_CLONE_FUNC_NAME);
2071 } else if (name_len == sizeof(ZEND_GET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME) - 1)) {
2072 if (fptr->common.num_args != 1) {
2073 zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ZSTR_VAL(ce->name), ZEND_GET_FUNC_NAME);
2074 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
2075 zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_GET_FUNC_NAME);
2076 }
2077 } else if (name_len == sizeof(ZEND_SET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME) - 1)) {
2078 if (fptr->common.num_args != 2) {
2079 zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), ZEND_SET_FUNC_NAME);
2080 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
2081 zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_SET_FUNC_NAME);
2082 }
2083 } else if (name_len == sizeof(ZEND_UNSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME) - 1)) {
2084 if (fptr->common.num_args != 1) {
2085 zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ZSTR_VAL(ce->name), ZEND_UNSET_FUNC_NAME);
2086 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
2087 zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_UNSET_FUNC_NAME);
2088 }
2089 } else if (name_len == sizeof(ZEND_ISSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME) - 1)) {
2090 if (fptr->common.num_args != 1) {
2091 zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ZSTR_VAL(ce->name), ZEND_ISSET_FUNC_NAME);
2092 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
2093 zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_ISSET_FUNC_NAME);
2094 }
2095 } else if (name_len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME) - 1)) {
2096 if (fptr->common.num_args != 2) {
2097 zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), ZEND_CALL_FUNC_NAME);
2098 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
2099 zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_CALL_FUNC_NAME);
2100 }
2101 } else if (name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME) - 1 &&
2102 !memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1)
2103 ) {
2104 if (fptr->common.num_args != 2) {
2105 zend_error(error_type, "Method %s::__callStatic() must take exactly 2 arguments", ZSTR_VAL(ce->name));
2106 } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
2107 zend_error(error_type, "Method %s::__callStatic() cannot take arguments by reference", ZSTR_VAL(ce->name));
2108 }
2109 } else if (name_len == sizeof(ZEND_TOSTRING_FUNC_NAME) - 1 &&
2110 !memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && fptr->common.num_args != 0
2111 ) {
2112 zend_error(error_type, "Method %s::%s() cannot take arguments", ZSTR_VAL(ce->name), ZEND_TOSTRING_FUNC_NAME);
2113 } else if (name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME) - 1 &&
2114 !memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && fptr->common.num_args != 0) {
2115 zend_error(error_type, "Method %s::%s() cannot take arguments", ZSTR_VAL(ce->name), ZEND_DEBUGINFO_FUNC_NAME);
2116 }
2117 }
2118
2119
2120
2121 ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_function_entry *functions, HashTable *function_table, int type)
2122 {
2123 const zend_function_entry *ptr = functions;
2124 zend_function function, *reg_function;
2125 zend_internal_function *internal_function = (zend_internal_function *)&function;
2126 int count=0, unload=0;
2127 HashTable *target_function_table = function_table;
2128 int error_type;
2129 zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL, *__debugInfo = NULL;
2130 zend_string *lowercase_name;
2131 size_t fname_len;
2132 const char *lc_class_name = NULL;
2133 size_t class_name_len = 0;
2134
2135 if (type==MODULE_PERSISTENT) {
2136 error_type = E_CORE_WARNING;
2137 } else {
2138 error_type = E_WARNING;
2139 }
2140
2141 if (!target_function_table) {
2142 target_function_table = CG(function_table);
2143 }
2144 internal_function->type = ZEND_INTERNAL_FUNCTION;
2145 internal_function->module = EG(current_module);
2146 memset(internal_function->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*));
2147
2148 if (scope) {
2149 class_name_len = ZSTR_LEN(scope->name);
2150 if ((lc_class_name = zend_memrchr(ZSTR_VAL(scope->name), '\\', class_name_len))) {
2151 ++lc_class_name;
2152 class_name_len -= (lc_class_name - ZSTR_VAL(scope->name));
2153 lc_class_name = zend_str_tolower_dup(lc_class_name, class_name_len);
2154 } else {
2155 lc_class_name = zend_str_tolower_dup(ZSTR_VAL(scope->name), class_name_len);
2156 }
2157 }
2158
2159 while (ptr->fname) {
2160 fname_len = strlen(ptr->fname);
2161 internal_function->handler = ptr->handler;
2162 internal_function->function_name = zend_new_interned_string(zend_string_init(ptr->fname, fname_len, 1));
2163 internal_function->scope = scope;
2164 internal_function->prototype = NULL;
2165 if (ptr->flags) {
2166 if (!(ptr->flags & ZEND_ACC_PPP_MASK)) {
2167 if (ptr->flags != ZEND_ACC_DEPRECATED || scope) {
2168 zend_error(error_type, "Invalid access level for %s%s%s() - access must be exactly one of public, protected or private", scope ? ZSTR_VAL(scope->name) : "", scope ? "::" : "", ptr->fname);
2169 }
2170 internal_function->fn_flags = ZEND_ACC_PUBLIC | ptr->flags;
2171 } else {
2172 internal_function->fn_flags = ptr->flags;
2173 }
2174 } else {
2175 internal_function->fn_flags = ZEND_ACC_PUBLIC;
2176 }
2177 if (ptr->arg_info) {
2178 zend_internal_function_info *info = (zend_internal_function_info*)ptr->arg_info;
2179
2180 internal_function->arg_info = (zend_internal_arg_info*)ptr->arg_info+1;
2181 internal_function->num_args = ptr->num_args;
2182
2183 if (info->required_num_args == (zend_uintptr_t)-1) {
2184 internal_function->required_num_args = ptr->num_args;
2185 } else {
2186 internal_function->required_num_args = info->required_num_args;
2187 }
2188 if (info->return_reference) {
2189 internal_function->fn_flags |= ZEND_ACC_RETURN_REFERENCE;
2190 }
2191 if (ptr->arg_info[ptr->num_args].is_variadic) {
2192 internal_function->fn_flags |= ZEND_ACC_VARIADIC;
2193
2194 internal_function->num_args--;
2195 }
2196 if (info->type_hint) {
2197 if (info->class_name) {
2198 ZEND_ASSERT(info->type_hint == IS_OBJECT);
2199 if (!scope && (!strcasecmp(info->class_name, "self") || !strcasecmp(info->class_name, "parent"))) {
2200 zend_error_noreturn(E_CORE_ERROR, "Cannot declare a return type of %s outside of a class scope", info->class_name);
2201 }
2202 }
2203
2204 internal_function->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE;
2205 }
2206 } else {
2207 internal_function->arg_info = NULL;
2208 internal_function->num_args = 0;
2209 internal_function->required_num_args = 0;
2210 }
2211 zend_set_function_arg_flags((zend_function*)internal_function);
2212 if (ptr->flags & ZEND_ACC_ABSTRACT) {
2213 if (scope) {
2214
2215 scope->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
2216 if (!(scope->ce_flags & ZEND_ACC_INTERFACE)) {
2217
2218
2219
2220 scope->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
2221 }
2222 }
2223 if (ptr->flags & ZEND_ACC_STATIC && (!scope || !(scope->ce_flags & ZEND_ACC_INTERFACE))) {
2224 zend_error(error_type, "Static function %s%s%s() cannot be abstract", scope ? ZSTR_VAL(scope->name) : "", scope ? "::" : "", ptr->fname);
2225 }
2226 } else {
2227 if (scope && (scope->ce_flags & ZEND_ACC_INTERFACE)) {
2228 efree((char*)lc_class_name);
2229 zend_error(error_type, "Interface %s cannot contain non abstract method %s()", ZSTR_VAL(scope->name), ptr->fname);
2230 return FAILURE;
2231 }
2232 if (!internal_function->handler) {
2233 if (scope) {
2234 efree((char*)lc_class_name);
2235 }
2236 zend_error(error_type, "Method %s%s%s() cannot be a NULL function", scope ? ZSTR_VAL(scope->name) : "", scope ? "::" : "", ptr->fname);
2237 zend_unregister_functions(functions, count, target_function_table);
2238 return FAILURE;
2239 }
2240 }
2241 lowercase_name = zend_string_alloc(fname_len, 1);
2242 zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ptr->fname, fname_len);
2243 lowercase_name = zend_new_interned_string(lowercase_name);
2244 reg_function = malloc(sizeof(zend_internal_function));
2245 memcpy(reg_function, &function, sizeof(zend_internal_function));
2246 if (zend_hash_add_ptr(target_function_table, lowercase_name, reg_function) == NULL) {
2247 unload=1;
2248 free(reg_function);
2249 zend_string_release(lowercase_name);
2250 break;
2251 }
2252
2253
2254 if (reg_function->common.arg_info && reg_function->common.num_args) {
2255 uint32_t i;
2256 for (i = 0; i < reg_function->common.num_args; i++) {
2257 if (reg_function->common.arg_info[i].class_name ||
2258 reg_function->common.arg_info[i].type_hint) {
2259 reg_function->common.fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
2260 break;
2261 }
2262 }
2263 }
2264
2265 if (scope) {
2266
2267
2268
2269
2270 if ((fname_len == class_name_len) && !ctor && !memcmp(ZSTR_VAL(lowercase_name), lc_class_name, class_name_len+1)) {
2271 ctor = reg_function;
2272 } else if (zend_string_equals_literal(lowercase_name, ZEND_CONSTRUCTOR_FUNC_NAME)) {
2273 ctor = reg_function;
2274 } else if (zend_string_equals_literal(lowercase_name, ZEND_DESTRUCTOR_FUNC_NAME)) {
2275 dtor = reg_function;
2276 if (internal_function->num_args) {
2277 zend_error(error_type, "Destructor %s::%s() cannot take arguments", ZSTR_VAL(scope->name), ptr->fname);
2278 }
2279 } else if (zend_string_equals_literal(lowercase_name, ZEND_CLONE_FUNC_NAME)) {
2280 clone = reg_function;
2281 } else if (zend_string_equals_literal(lowercase_name, ZEND_CALL_FUNC_NAME)) {
2282 __call = reg_function;
2283 } else if (zend_string_equals_literal(lowercase_name, ZEND_CALLSTATIC_FUNC_NAME)) {
2284 __callstatic = reg_function;
2285 } else if (zend_string_equals_literal(lowercase_name, ZEND_TOSTRING_FUNC_NAME)) {
2286 __tostring = reg_function;
2287 } else if (zend_string_equals_literal(lowercase_name, ZEND_GET_FUNC_NAME)) {
2288 __get = reg_function;
2289 scope->ce_flags |= ZEND_ACC_USE_GUARDS;
2290 } else if (zend_string_equals_literal(lowercase_name, ZEND_SET_FUNC_NAME)) {
2291 __set = reg_function;
2292 scope->ce_flags |= ZEND_ACC_USE_GUARDS;
2293 } else if (zend_string_equals_literal(lowercase_name, ZEND_UNSET_FUNC_NAME)) {
2294 __unset = reg_function;
2295 scope->ce_flags |= ZEND_ACC_USE_GUARDS;
2296 } else if (zend_string_equals_literal(lowercase_name, ZEND_ISSET_FUNC_NAME)) {
2297 __isset = reg_function;
2298 scope->ce_flags |= ZEND_ACC_USE_GUARDS;
2299 } else if (zend_string_equals_literal(lowercase_name, ZEND_DEBUGINFO_FUNC_NAME)) {
2300 __debugInfo = reg_function;
2301 } else {
2302 reg_function = NULL;
2303 }
2304 if (reg_function) {
2305 zend_check_magic_method_implementation(scope, reg_function, error_type);
2306 }
2307 }
2308 ptr++;
2309 count++;
2310 zend_string_release(lowercase_name);
2311 }
2312 if (unload) {
2313 if (scope) {
2314 efree((char*)lc_class_name);
2315 }
2316 while (ptr->fname) {
2317 fname_len = strlen(ptr->fname);
2318 lowercase_name = zend_string_alloc(fname_len, 0);
2319 zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ptr->fname, fname_len);
2320 if (zend_hash_exists(target_function_table, lowercase_name)) {
2321 zend_error(error_type, "Function registration failed - duplicate name - %s%s%s", scope ? ZSTR_VAL(scope->name) : "", scope ? "::" : "", ptr->fname);
2322 }
2323 zend_string_free(lowercase_name);
2324 ptr++;
2325 }
2326 zend_unregister_functions(functions, count, target_function_table);
2327 return FAILURE;
2328 }
2329 if (scope) {
2330 scope->constructor = ctor;
2331 scope->destructor = dtor;
2332 scope->clone = clone;
2333 scope->__call = __call;
2334 scope->__callstatic = __callstatic;
2335 scope->__tostring = __tostring;
2336 scope->__get = __get;
2337 scope->__set = __set;
2338 scope->__unset = __unset;
2339 scope->__isset = __isset;
2340 scope->__debugInfo = __debugInfo;
2341 if (ctor) {
2342 ctor->common.fn_flags |= ZEND_ACC_CTOR;
2343 if (ctor->common.fn_flags & ZEND_ACC_STATIC) {
2344 zend_error(error_type, "Constructor %s::%s() cannot be static", ZSTR_VAL(scope->name), ZSTR_VAL(ctor->common.function_name));
2345 }
2346 ctor->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2347 }
2348 if (dtor) {
2349 dtor->common.fn_flags |= ZEND_ACC_DTOR;
2350 if (dtor->common.fn_flags & ZEND_ACC_STATIC) {
2351 zend_error(error_type, "Destructor %s::%s() cannot be static", ZSTR_VAL(scope->name), ZSTR_VAL(dtor->common.function_name));
2352 }
2353 dtor->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2354 }
2355 if (clone) {
2356 clone->common.fn_flags |= ZEND_ACC_CLONE;
2357 if (clone->common.fn_flags & ZEND_ACC_STATIC) {
2358 zend_error(error_type, "Constructor %s::%s() cannot be static", ZSTR_VAL(scope->name), ZSTR_VAL(clone->common.function_name));
2359 }
2360 clone->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2361 }
2362 if (__call) {
2363 if (__call->common.fn_flags & ZEND_ACC_STATIC) {
2364 zend_error(error_type, "Method %s::%s() cannot be static", ZSTR_VAL(scope->name), ZSTR_VAL(__call->common.function_name));
2365 }
2366 __call->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2367 }
2368 if (__callstatic) {
2369 if (!(__callstatic->common.fn_flags & ZEND_ACC_STATIC)) {
2370 zend_error(error_type, "Method %s::%s() must be static", ZSTR_VAL(scope->name), ZSTR_VAL(__callstatic->common.function_name));
2371 }
2372 __callstatic->common.fn_flags |= ZEND_ACC_STATIC;
2373 }
2374 if (__tostring) {
2375 if (__tostring->common.fn_flags & ZEND_ACC_STATIC) {
2376 zend_error(error_type, "Method %s::%s() cannot be static", ZSTR_VAL(scope->name), ZSTR_VAL(__tostring->common.function_name));
2377 }
2378 __tostring->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2379 }
2380 if (__get) {
2381 if (__get->common.fn_flags & ZEND_ACC_STATIC) {
2382 zend_error(error_type, "Method %s::%s() cannot be static", ZSTR_VAL(scope->name), ZSTR_VAL(__get->common.function_name));
2383 }
2384 __get->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2385 }
2386 if (__set) {
2387 if (__set->common.fn_flags & ZEND_ACC_STATIC) {
2388 zend_error(error_type, "Method %s::%s() cannot be static", ZSTR_VAL(scope->name), ZSTR_VAL(__set->common.function_name));
2389 }
2390 __set->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2391 }
2392 if (__unset) {
2393 if (__unset->common.fn_flags & ZEND_ACC_STATIC) {
2394 zend_error(error_type, "Method %s::%s() cannot be static", ZSTR_VAL(scope->name), ZSTR_VAL(__unset->common.function_name));
2395 }
2396 __unset->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2397 }
2398 if (__isset) {
2399 if (__isset->common.fn_flags & ZEND_ACC_STATIC) {
2400 zend_error(error_type, "Method %s::%s() cannot be static", ZSTR_VAL(scope->name), ZSTR_VAL(__isset->common.function_name));
2401 }
2402 __isset->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2403 }
2404 if (__debugInfo) {
2405 if (__debugInfo->common.fn_flags & ZEND_ACC_STATIC) {
2406 zend_error(error_type, "Method %s::%s() cannot be static", ZSTR_VAL(scope->name), ZSTR_VAL(__debugInfo->common.function_name));
2407 }
2408 }
2409
2410 if (ctor && ctor->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && ctor->common.fn_flags & ZEND_ACC_CTOR) {
2411 zend_error_noreturn(E_CORE_ERROR, "Constructor %s::%s() cannot declare a return type", ZSTR_VAL(scope->name), ZSTR_VAL(ctor->common.function_name));
2412 }
2413
2414 if (dtor && dtor->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && dtor->common.fn_flags & ZEND_ACC_DTOR) {
2415 zend_error_noreturn(E_CORE_ERROR, "Destructor %s::%s() cannot declare a return type", ZSTR_VAL(scope->name), ZSTR_VAL(dtor->common.function_name));
2416 }
2417
2418 if (clone && clone->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && dtor->common.fn_flags & ZEND_ACC_DTOR) {
2419 zend_error_noreturn(E_CORE_ERROR, "%s::%s() cannot declare a return type", ZSTR_VAL(scope->name), ZSTR_VAL(clone->common.function_name));
2420 }
2421 efree((char*)lc_class_name);
2422 }
2423 return SUCCESS;
2424 }
2425
2426
2427
2428
2429
2430 ZEND_API void zend_unregister_functions(const zend_function_entry *functions, int count, HashTable *function_table)
2431 {
2432 const zend_function_entry *ptr = functions;
2433 int i=0;
2434 HashTable *target_function_table = function_table;
2435 zend_string *lowercase_name;
2436 size_t fname_len;
2437
2438 if (!target_function_table) {
2439 target_function_table = CG(function_table);
2440 }
2441 while (ptr->fname) {
2442 if (count!=-1 && i>=count) {
2443 break;
2444 }
2445 fname_len = strlen(ptr->fname);
2446 lowercase_name = zend_string_alloc(fname_len, 0);
2447 zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ptr->fname, fname_len);
2448 zend_hash_del(target_function_table, lowercase_name);
2449 zend_string_free(lowercase_name);
2450 ptr++;
2451 i++;
2452 }
2453 }
2454
2455
2456 ZEND_API int zend_startup_module(zend_module_entry *module)
2457 {
2458 if ((module = zend_register_internal_module(module)) != NULL && zend_startup_module_ex(module) == SUCCESS) {
2459 return SUCCESS;
2460 }
2461 return FAILURE;
2462 }
2463
2464
2465 ZEND_API int zend_get_module_started(const char *module_name)
2466 {
2467 zend_module_entry *module;
2468
2469 module = zend_hash_str_find_ptr(&module_registry, module_name, strlen(module_name));
2470 return (module && module->module_started) ? SUCCESS : FAILURE;
2471 }
2472
2473
2474 static int clean_module_class(zval *el, void *arg)
2475 {
2476 zend_class_entry *ce = (zend_class_entry *)Z_PTR_P(el);
2477 int module_number = *(int *)arg;
2478 if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->module_number == module_number) {
2479 return ZEND_HASH_APPLY_REMOVE;
2480 } else {
2481 return ZEND_HASH_APPLY_KEEP;
2482 }
2483 }
2484
2485
2486 static void clean_module_classes(int module_number)
2487 {
2488 zend_hash_apply_with_argument(EG(class_table), clean_module_class, (void *) &module_number);
2489 }
2490
2491
2492 void module_destructor(zend_module_entry *module)
2493 {
2494
2495 if (module->type == MODULE_TEMPORARY) {
2496 zend_clean_module_rsrc_dtors(module->module_number);
2497 clean_module_constants(module->module_number);
2498 clean_module_classes(module->module_number);
2499 }
2500
2501 if (module->module_started && module->module_shutdown_func) {
2502 #if 0
2503 zend_printf("%s: Module shutdown\n", module->name);
2504 #endif
2505 module->module_shutdown_func(module->type, module->module_number);
2506 }
2507
2508
2509 if (module->globals_size) {
2510 #ifdef ZTS
2511 if (*module->globals_id_ptr) {
2512 ts_free_id(*module->globals_id_ptr);
2513 }
2514 #else
2515 if (module->globals_dtor) {
2516 module->globals_dtor(module->globals_ptr);
2517 }
2518 #endif
2519 }
2520
2521 module->module_started=0;
2522 if (module->functions) {
2523 zend_unregister_functions(module->functions, -1, NULL);
2524 }
2525
2526 #if HAVE_LIBDL
2527 #if !(defined(NETWARE) && defined(APACHE_1_BUILD))
2528 if (module->handle && !getenv("ZEND_DONT_UNLOAD_MODULES")) {
2529 DL_UNLOAD(module->handle);
2530 }
2531 #endif
2532 #endif
2533 }
2534
2535
2536 ZEND_API void zend_activate_modules(void)
2537 {
2538 zend_module_entry **p = module_request_startup_handlers;
2539
2540 while (*p) {
2541 zend_module_entry *module = *p;
2542
2543 if (module->request_startup_func(module->type, module->module_number)==FAILURE) {
2544 zend_error(E_WARNING, "request_startup() for %s module failed", module->name);
2545 exit(1);
2546 }
2547 p++;
2548 }
2549 }
2550
2551
2552
2553 static int module_registry_cleanup(zval *zv)
2554 {
2555 zend_module_entry *module = Z_PTR_P(zv);
2556
2557 if (module->request_shutdown_func) {
2558 #if 0
2559 zend_printf("%s: Request shutdown\n", module->name);
2560 #endif
2561 module->request_shutdown_func(module->type, module->module_number);
2562 }
2563 return 0;
2564 }
2565
2566
2567 ZEND_API void zend_deactivate_modules(void)
2568 {
2569 EG(current_execute_data) = NULL;
2570
2571 zend_try {
2572 if (EG(full_tables_cleanup)) {
2573 zend_hash_reverse_apply(&module_registry, module_registry_cleanup);
2574 } else {
2575 zend_module_entry **p = module_request_shutdown_handlers;
2576
2577 while (*p) {
2578 zend_module_entry *module = *p;
2579
2580 module->request_shutdown_func(module->type, module->module_number);
2581 p++;
2582 }
2583 }
2584 } zend_end_try();
2585 }
2586
2587
2588 ZEND_API void zend_cleanup_internal_classes(void)
2589 {
2590 zend_class_entry **p = class_cleanup_handlers;
2591
2592 while (*p) {
2593 zend_cleanup_internal_class_data(*p);
2594 p++;
2595 }
2596 }
2597
2598
2599 int module_registry_unload_temp(const zend_module_entry *module)
2600 {
2601 return (module->type == MODULE_TEMPORARY) ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_STOP;
2602 }
2603
2604
2605 static int module_registry_unload_temp_wrapper(zval *el)
2606 {
2607 zend_module_entry *module = (zend_module_entry *)Z_PTR_P(el);
2608 return module_registry_unload_temp((const zend_module_entry *)module);
2609 }
2610
2611
2612 static int exec_done_cb(zval *el)
2613 {
2614 zend_module_entry *module = (zend_module_entry *)Z_PTR_P(el);
2615 if (module->post_deactivate_func) {
2616 module->post_deactivate_func();
2617 }
2618 return 0;
2619 }
2620
2621
2622 ZEND_API void zend_post_deactivate_modules(void)
2623 {
2624 if (EG(full_tables_cleanup)) {
2625 zend_hash_apply(&module_registry, exec_done_cb);
2626 zend_hash_reverse_apply(&module_registry, module_registry_unload_temp_wrapper);
2627 } else {
2628 zend_module_entry **p = module_post_deactivate_handlers;
2629
2630 while (*p) {
2631 zend_module_entry *module = *p;
2632
2633 module->post_deactivate_func();
2634 p++;
2635 }
2636 }
2637 }
2638
2639
2640
2641 ZEND_API int zend_next_free_module(void)
2642 {
2643 return zend_hash_num_elements(&module_registry) + 1;
2644 }
2645
2646
2647 static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class_entry, uint32_t ce_flags)
2648 {
2649 zend_class_entry *class_entry = malloc(sizeof(zend_class_entry));
2650 zend_string *lowercase_name = zend_string_alloc(ZSTR_LEN(orig_class_entry->name), 1);
2651 *class_entry = *orig_class_entry;
2652
2653 class_entry->type = ZEND_INTERNAL_CLASS;
2654 zend_initialize_class_data(class_entry, 0);
2655 class_entry->ce_flags = ce_flags | ZEND_ACC_CONSTANTS_UPDATED;
2656 class_entry->info.internal.module = EG(current_module);
2657
2658 if (class_entry->info.internal.builtin_functions) {
2659 zend_register_functions(class_entry, class_entry->info.internal.builtin_functions, &class_entry->function_table, MODULE_PERSISTENT);
2660 }
2661
2662 zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ZSTR_VAL(orig_class_entry->name), ZSTR_LEN(class_entry->name));
2663 lowercase_name = zend_new_interned_string(lowercase_name);
2664 zend_hash_update_ptr(CG(class_table), lowercase_name, class_entry);
2665 zend_string_release(lowercase_name);
2666 return class_entry;
2667 }
2668
2669
2670
2671
2672
2673
2674
2675 ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce)
2676 {
2677 zend_class_entry *register_class;
2678
2679 register_class = zend_register_internal_class(class_entry);
2680
2681 if (parent_ce) {
2682 zend_do_inheritance(register_class, parent_ce);
2683 }
2684 return register_class;
2685 }
2686
2687
2688 ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_interfaces, ...)
2689 {
2690 zend_class_entry *interface_entry;
2691 va_list interface_list;
2692 va_start(interface_list, num_interfaces);
2693
2694 while (num_interfaces--) {
2695 interface_entry = va_arg(interface_list, zend_class_entry *);
2696 zend_do_implement_interface(class_entry, interface_entry);
2697 }
2698
2699 va_end(interface_list);
2700 }
2701
2702
2703
2704
2705 ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *orig_class_entry)
2706 {
2707 return do_register_internal_class(orig_class_entry, 0);
2708 }
2709
2710
2711 ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry)
2712 {
2713 return do_register_internal_class(orig_class_entry, ZEND_ACC_INTERFACE);
2714 }
2715
2716
2717 ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce)
2718 {
2719 zend_string *lcname;
2720
2721 if (name[0] == '\\') {
2722 lcname = zend_string_alloc(name_len-1, 1);
2723 zend_str_tolower_copy(ZSTR_VAL(lcname), name+1, name_len-1);
2724 } else {
2725 lcname = zend_string_alloc(name_len, 1);
2726 zend_str_tolower_copy(ZSTR_VAL(lcname), name, name_len);
2727 }
2728
2729 zend_assert_valid_class_name(lcname);
2730
2731 ce = zend_hash_add_ptr(CG(class_table), lcname, ce);
2732 zend_string_release(lcname);
2733 if (ce) {
2734 ce->refcount++;
2735 return SUCCESS;
2736 }
2737 return FAILURE;
2738 }
2739
2740
2741 ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_length, zend_bool is_ref, int num_symbol_tables, ...)
2742 {
2743 HashTable *symbol_table;
2744 va_list symbol_table_list;
2745
2746 if (num_symbol_tables <= 0) return FAILURE;
2747
2748 if (is_ref) {
2749 ZVAL_MAKE_REF(symbol);
2750 }
2751
2752 va_start(symbol_table_list, num_symbol_tables);
2753 while (num_symbol_tables-- > 0) {
2754 symbol_table = va_arg(symbol_table_list, HashTable *);
2755 zend_hash_str_update(symbol_table, name, name_length, symbol);
2756 if (Z_REFCOUNTED_P(symbol)) {
2757 Z_ADDREF_P(symbol);
2758 }
2759 }
2760 va_end(symbol_table_list);
2761 return SUCCESS;
2762 }
2763
2764
2765
2766
2767
2768
2769 ZEND_API ZEND_FUNCTION(display_disabled_function)
2770 {
2771 zend_error(E_WARNING, "%s() has been disabled for security reasons", get_active_function_name());
2772 }
2773
2774
2775 ZEND_API int zend_disable_function(char *function_name, size_t function_name_length)
2776 {
2777 zend_internal_function *func;
2778 if ((func = zend_hash_str_find_ptr(CG(function_table), function_name, function_name_length))) {
2779 func->fn_flags &= ~(ZEND_ACC_VARIADIC | ZEND_ACC_HAS_TYPE_HINTS);
2780 func->num_args = 0;
2781 func->arg_info = NULL;
2782 func->handler = ZEND_FN(display_disabled_function);
2783 return SUCCESS;
2784 }
2785 return FAILURE;
2786 }
2787
2788
2789 #ifdef ZEND_WIN32
2790 #pragma optimize("", off)
2791 #endif
2792 static zend_object *display_disabled_class(zend_class_entry *class_type)
2793 {
2794 zend_object *intern;
2795
2796 intern = zend_objects_new(class_type);
2797 zend_error(E_WARNING, "%s() has been disabled for security reasons", ZSTR_VAL(class_type->name));
2798 return intern;
2799 }
2800 #ifdef ZEND_WIN32
2801 #pragma optimize("", on)
2802 #endif
2803
2804
2805 static const zend_function_entry disabled_class_new[] = {
2806 ZEND_FE_END
2807 };
2808
2809 ZEND_API int zend_disable_class(char *class_name, size_t class_name_length)
2810 {
2811 zend_class_entry *disabled_class;
2812 zend_string *key;
2813
2814 key = zend_string_alloc(class_name_length, 0);
2815 zend_str_tolower_copy(ZSTR_VAL(key), class_name, class_name_length);
2816 disabled_class = zend_hash_find_ptr(CG(class_table), key);
2817 if (!disabled_class) {
2818 return FAILURE;
2819 }
2820 INIT_CLASS_ENTRY_INIT_METHODS((*disabled_class), disabled_class_new, NULL, NULL, NULL, NULL, NULL);
2821 disabled_class->create_object = display_disabled_class;
2822 zend_hash_clean(&disabled_class->function_table);
2823 return SUCCESS;
2824 }
2825
2826
2827 static int zend_is_callable_check_class(zend_string *name, zend_fcall_info_cache *fcc, int *strict_class, char **error)
2828 {
2829 int ret = 0;
2830 zend_class_entry *ce;
2831 size_t name_len = ZSTR_LEN(name);
2832 zend_string *lcname;
2833 ALLOCA_FLAG(use_heap);
2834
2835 ZSTR_ALLOCA_ALLOC(lcname, name_len, use_heap);
2836 zend_str_tolower_copy(ZSTR_VAL(lcname), ZSTR_VAL(name), name_len);
2837
2838 *strict_class = 0;
2839 if (zend_string_equals_literal(lcname, "self")) {
2840 if (!EG(scope)) {
2841 if (error) *error = estrdup("cannot access self:: when no class scope is active");
2842 } else {
2843 fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
2844 fcc->calling_scope = EG(scope);
2845 if (!fcc->object) {
2846 fcc->object = zend_get_this_object(EG(current_execute_data));
2847 }
2848 ret = 1;
2849 }
2850 } else if (zend_string_equals_literal(lcname, "parent")) {
2851 if (!EG(scope)) {
2852 if (error) *error = estrdup("cannot access parent:: when no class scope is active");
2853 } else if (!EG(scope)->parent) {
2854 if (error) *error = estrdup("cannot access parent:: when current class scope has no parent");
2855 } else {
2856 fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
2857 fcc->calling_scope = EG(scope)->parent;
2858 if (!fcc->object) {
2859 fcc->object = zend_get_this_object(EG(current_execute_data));
2860 }
2861 *strict_class = 1;
2862 ret = 1;
2863 }
2864 } else if (zend_string_equals_literal(lcname, "static")) {
2865 zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data));
2866
2867 if (!called_scope) {
2868 if (error) *error = estrdup("cannot access static:: when no class scope is active");
2869 } else {
2870 fcc->called_scope = called_scope;
2871 fcc->calling_scope = called_scope;
2872 if (!fcc->object) {
2873 fcc->object = zend_get_this_object(EG(current_execute_data));
2874 }
2875 *strict_class = 1;
2876 ret = 1;
2877 }
2878 } else if ((ce = zend_lookup_class_ex(name, NULL, 1)) != NULL) {
2879 zend_class_entry *scope;
2880 zend_execute_data *ex = EG(current_execute_data);
2881
2882 while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
2883 ex = ex->prev_execute_data;
2884 }
2885 scope = ex ? ex->func->common.scope : NULL;
2886 fcc->calling_scope = ce;
2887 if (scope && !fcc->object) {
2888 zend_object *object = zend_get_this_object(EG(current_execute_data));
2889
2890 if (object &&
2891 instanceof_function(object->ce, scope) &&
2892 instanceof_function(scope, fcc->calling_scope)) {
2893 fcc->object = object;
2894 fcc->called_scope = object->ce;
2895 } else {
2896 fcc->called_scope = fcc->calling_scope;
2897 }
2898 } else {
2899 fcc->called_scope = fcc->object ? fcc->object->ce : fcc->calling_scope;
2900 }
2901 *strict_class = 1;
2902 ret = 1;
2903 } else {
2904 if (error) zend_spprintf(error, 0, "class '%.*s' not found", name_len, ZSTR_VAL(name));
2905 }
2906 ZSTR_ALLOCA_FREE(lcname, use_heap);
2907 return ret;
2908 }
2909
2910
2911 static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fcall_info_cache *fcc, int strict_class, char **error)
2912 {
2913 zend_class_entry *ce_org = fcc->calling_scope;
2914 int retval = 0;
2915 zend_string *mname, *cname;
2916 zend_string *lmname;
2917 const char *colon;
2918 size_t clen, mlen;
2919 zend_class_entry *last_scope;
2920 HashTable *ftable;
2921 int call_via_handler = 0;
2922 ALLOCA_FLAG(use_heap)
2923
2924 if (error) {
2925 *error = NULL;
2926 }
2927
2928 fcc->calling_scope = NULL;
2929 fcc->function_handler = NULL;
2930
2931 if (!ce_org) {
2932 zend_string *lmname;
2933
2934
2935 if (UNEXPECTED(Z_STRVAL_P(callable)[0] == '\\')) {
2936 ZSTR_ALLOCA_INIT(lmname, Z_STRVAL_P(callable) + 1, Z_STRLEN_P(callable) - 1, use_heap);
2937 } else {
2938 lmname = Z_STR_P(callable);
2939 }
2940
2941
2942 if (EXPECTED((fcc->function_handler = zend_hash_find_ptr(EG(function_table), lmname)) != NULL)) {
2943 if (lmname != Z_STR_P(callable)) {
2944 ZSTR_ALLOCA_FREE(lmname, use_heap);
2945 }
2946 fcc->initialized = 1;
2947 return 1;
2948 } else {
2949 if (lmname == Z_STR_P(callable)) {
2950 ZSTR_ALLOCA_INIT(lmname, Z_STRVAL_P(callable), Z_STRLEN_P(callable), use_heap);
2951 } else {
2952 zend_string_forget_hash_val(lmname);
2953 }
2954 zend_str_tolower(ZSTR_VAL(lmname), ZSTR_LEN(lmname));
2955 if ((fcc->function_handler = zend_hash_find_ptr(EG(function_table), lmname)) != NULL) {
2956 ZSTR_ALLOCA_FREE(lmname, use_heap);
2957 fcc->initialized = 1;
2958 return 1;
2959 }
2960 }
2961 if (lmname != Z_STR_P(callable)) {
2962 ZSTR_ALLOCA_FREE(lmname, use_heap);
2963 }
2964 }
2965
2966
2967 if ((colon = zend_memrchr(Z_STRVAL_P(callable), ':', Z_STRLEN_P(callable))) != NULL &&
2968 colon > Z_STRVAL_P(callable) &&
2969 *(colon-1) == ':'
2970 ) {
2971 colon--;
2972 clen = colon - Z_STRVAL_P(callable);
2973 mlen = Z_STRLEN_P(callable) - clen - 2;
2974
2975 if (colon == Z_STRVAL_P(callable)) {
2976 if (error) zend_spprintf(error, 0, "invalid function name");
2977 return 0;
2978 }
2979
2980
2981
2982 last_scope = EG(scope);
2983 if (ce_org) {
2984 EG(scope) = ce_org;
2985 }
2986
2987 cname = zend_string_init(Z_STRVAL_P(callable), clen, 0);
2988 if (!zend_is_callable_check_class(cname, fcc, &strict_class, error)) {
2989 zend_string_release(cname);
2990 EG(scope) = last_scope;
2991 return 0;
2992 }
2993 zend_string_release(cname);
2994 EG(scope) = last_scope;
2995
2996 ftable = &fcc->calling_scope->function_table;
2997 if (ce_org && !instanceof_function(ce_org, fcc->calling_scope)) {
2998 if (error) zend_spprintf(error, 0, "class '%s' is not a subclass of '%s'", ZSTR_VAL(ce_org->name), ZSTR_VAL(fcc->calling_scope->name));
2999 return 0;
3000 }
3001 mname = zend_string_init(Z_STRVAL_P(callable) + clen + 2, mlen, 0);
3002 } else if (ce_org) {
3003
3004 mlen = Z_STRLEN_P(callable);
3005 mname = Z_STR_P(callable);
3006 zend_string_addref(mname);
3007 ftable = &ce_org->function_table;
3008 fcc->calling_scope = ce_org;
3009 } else {
3010
3011 if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) {
3012 zend_spprintf(error, 0, "function '%s' not found or invalid function name", Z_STRVAL_P(callable));
3013 }
3014 return 0;
3015 }
3016
3017 lmname = zend_string_tolower(mname);
3018 if (strict_class &&
3019 fcc->calling_scope &&
3020 zend_string_equals_literal(lmname, ZEND_CONSTRUCTOR_FUNC_NAME)) {
3021 fcc->function_handler = fcc->calling_scope->constructor;
3022 if (fcc->function_handler) {
3023 retval = 1;
3024 }
3025 } else if ((fcc->function_handler = zend_hash_find_ptr(ftable, lmname)) != NULL) {
3026 retval = 1;
3027 if ((fcc->function_handler->op_array.fn_flags & ZEND_ACC_CHANGED) &&
3028 !strict_class && EG(scope) &&
3029 instanceof_function(fcc->function_handler->common.scope, EG(scope))) {
3030 zend_function *priv_fbc;
3031
3032 if ((priv_fbc = zend_hash_find_ptr(&EG(scope)->function_table, lmname)) != NULL
3033 && priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
3034 && priv_fbc->common.scope == EG(scope)) {
3035 fcc->function_handler = priv_fbc;
3036 }
3037 }
3038 if ((check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0 &&
3039 (fcc->calling_scope &&
3040 ((fcc->object && fcc->calling_scope->__call) ||
3041 (!fcc->object && fcc->calling_scope->__callstatic)))) {
3042 if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
3043 if (!zend_check_private(fcc->function_handler, fcc->object ? fcc->object->ce : EG(scope), lmname)) {
3044 retval = 0;
3045 fcc->function_handler = NULL;
3046 goto get_function_via_handler;
3047 }
3048 } else if (fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED) {
3049 if (!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) {
3050 retval = 0;
3051 fcc->function_handler = NULL;
3052 goto get_function_via_handler;
3053 }
3054 }
3055 }
3056 } else {
3057 get_function_via_handler:
3058 if (fcc->object && fcc->calling_scope == ce_org) {
3059 if (strict_class && ce_org->__call) {
3060 fcc->function_handler = zend_get_call_trampoline_func(ce_org, mname, 0);
3061 call_via_handler = 1;
3062 retval = 1;
3063 } else if (fcc->object->handlers->get_method) {
3064 fcc->function_handler = fcc->object->handlers->get_method(&fcc->object, mname, NULL);
3065 if (fcc->function_handler) {
3066 if (strict_class &&
3067 (!fcc->function_handler->common.scope ||
3068 !instanceof_function(ce_org, fcc->function_handler->common.scope))) {
3069 if (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
3070 if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
3071 zend_string_release(fcc->function_handler->common.function_name);
3072 }
3073 zend_free_trampoline(fcc->function_handler);
3074 }
3075 } else {
3076 retval = 1;
3077 call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
3078 }
3079 }
3080 }
3081 } else if (fcc->calling_scope) {
3082 if (fcc->calling_scope->get_static_method) {
3083 fcc->function_handler = fcc->calling_scope->get_static_method(fcc->calling_scope, mname);
3084 } else {
3085 fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, mname, NULL);
3086 }
3087 if (fcc->function_handler) {
3088 retval = 1;
3089 call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
3090 if (call_via_handler && !fcc->object) {
3091 zend_object *object = zend_get_this_object(EG(current_execute_data));
3092 if (object &&
3093 instanceof_function(object->ce, fcc->calling_scope)) {
3094 fcc->object = object;
3095 }
3096 }
3097 }
3098 }
3099 }
3100
3101 if (retval) {
3102 if (fcc->calling_scope && !call_via_handler) {
3103 if (!fcc->object && (fcc->function_handler->common.fn_flags & ZEND_ACC_ABSTRACT)) {
3104 if (error) {
3105 zend_spprintf(error, 0, "cannot call abstract method %s::%s()", ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(fcc->function_handler->common.function_name));
3106 retval = 0;
3107 } else {
3108 zend_throw_error(NULL, "Cannot call abstract method %s::%s()", ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(fcc->function_handler->common.function_name));
3109 return 0;
3110 }
3111 } else if (!fcc->object && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) {
3112 int severity;
3113 char *verb;
3114 if (fcc->function_handler->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
3115 severity = E_DEPRECATED;
3116 verb = "should not";
3117 } else {
3118
3119 severity = E_ERROR;
3120 verb = "cannot";
3121 }
3122 if ((check_flags & IS_CALLABLE_CHECK_IS_STATIC) != 0) {
3123 retval = 0;
3124 }
3125 if (error) {
3126 zend_spprintf(error, 0, "non-static method %s::%s() %s be called statically", ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(fcc->function_handler->common.function_name), verb);
3127 if (severity != E_DEPRECATED) {
3128 retval = 0;
3129 }
3130 } else if (retval) {
3131 if (severity == E_ERROR) {
3132 zend_throw_error(NULL, "Non-static method %s::%s() %s be called statically", ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(fcc->function_handler->common.function_name), verb);
3133 } else {
3134 zend_error(severity, "Non-static method %s::%s() %s be called statically", ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(fcc->function_handler->common.function_name), verb);
3135 }
3136 }
3137 }
3138 if (retval && (check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) {
3139 if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
3140 if (!zend_check_private(fcc->function_handler, fcc->object ? fcc->object->ce : EG(scope), lmname)) {
3141 if (error) {
3142 if (*error) {
3143 efree(*error);
3144 }
3145 zend_spprintf(error, 0, "cannot access private method %s::%s()", ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(fcc->function_handler->common.function_name));
3146 }
3147 retval = 0;
3148 }
3149 } else if ((fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED)) {
3150 if (!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) {
3151 if (error) {
3152 if (*error) {
3153 efree(*error);
3154 }
3155 zend_spprintf(error, 0, "cannot access protected method %s::%s()", ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(fcc->function_handler->common.function_name));
3156 }
3157 retval = 0;
3158 }
3159 }
3160 }
3161 }
3162 } else if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) {
3163 if (fcc->calling_scope) {
3164 if (error) zend_spprintf(error, 0, "class '%s' does not have a method '%s'", ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(mname));
3165 } else {
3166 if (error) zend_spprintf(error, 0, "function '%s' does not exist", ZSTR_VAL(mname));
3167 }
3168 }
3169 zend_string_release(lmname);
3170 zend_string_release(mname);
3171
3172 if (fcc->object) {
3173 fcc->called_scope = fcc->object->ce;
3174 }
3175 if (retval) {
3176 fcc->initialized = 1;
3177 }
3178 return retval;
3179 }
3180
3181
3182 ZEND_API zend_bool zend_is_callable_ex(zval *callable, zend_object *object, uint check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error)
3183 {
3184 zend_bool ret;
3185 zend_fcall_info_cache fcc_local;
3186
3187 if (callable_name) {
3188 *callable_name = NULL;
3189 }
3190 if (fcc == NULL) {
3191 fcc = &fcc_local;
3192 }
3193 if (error) {
3194 *error = NULL;
3195 }
3196
3197 fcc->initialized = 0;
3198 fcc->calling_scope = NULL;
3199 fcc->called_scope = NULL;
3200 fcc->function_handler = NULL;
3201 fcc->object = NULL;
3202
3203 if (object &&
3204 (!EG(objects_store).object_buckets ||
3205 !IS_OBJ_VALID(EG(objects_store).object_buckets[object->handle]))) {
3206 return 0;
3207 }
3208
3209 again:
3210 switch (Z_TYPE_P(callable)) {
3211 case IS_STRING:
3212 if (object) {
3213 fcc->object = object;
3214 fcc->calling_scope = object->ce;
3215 if (callable_name) {
3216 char *ptr;
3217
3218 *callable_name = zend_string_alloc(ZSTR_LEN(fcc->calling_scope->name) + Z_STRLEN_P(callable) + sizeof("::") - 1, 0);
3219 ptr = ZSTR_VAL(*callable_name);
3220 memcpy(ptr, ZSTR_VAL(fcc->calling_scope->name), ZSTR_LEN(fcc->calling_scope->name));
3221 ptr += ZSTR_LEN(fcc->calling_scope->name);
3222 memcpy(ptr, "::", sizeof("::") - 1);
3223 ptr += sizeof("::") - 1;
3224 memcpy(ptr, Z_STRVAL_P(callable), Z_STRLEN_P(callable) + 1);
3225 }
3226 } else if (callable_name) {
3227 *callable_name = zend_string_copy(Z_STR_P(callable));
3228 }
3229 if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
3230 fcc->called_scope = fcc->calling_scope;
3231 return 1;
3232 }
3233
3234 ret = zend_is_callable_check_func(check_flags, callable, fcc, 0, error);
3235 if (fcc == &fcc_local &&
3236 fcc->function_handler &&
3237 ((fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) ||
3238 fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
3239 fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
3240 if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
3241 zend_string_release(fcc->function_handler->common.function_name);
3242 }
3243 zend_free_trampoline(fcc->function_handler);
3244 }
3245 return ret;
3246
3247 case IS_ARRAY:
3248 {
3249 zval *method = NULL;
3250 zval *obj = NULL;
3251 int strict_class = 0;
3252
3253 if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
3254 obj = zend_hash_index_find(Z_ARRVAL_P(callable), 0);
3255 method = zend_hash_index_find(Z_ARRVAL_P(callable), 1);
3256 }
3257
3258 do {
3259 if (obj == NULL || method == NULL) {
3260 break;
3261 }
3262
3263 ZVAL_DEREF(method);
3264 if (Z_TYPE_P(method) != IS_STRING) {
3265 break;
3266 }
3267
3268 ZVAL_DEREF(obj);
3269 if (Z_TYPE_P(obj) == IS_STRING) {
3270 if (callable_name) {
3271 char *ptr;
3272
3273
3274 *callable_name = zend_string_alloc(Z_STRLEN_P(obj) + Z_STRLEN_P(method) + sizeof("::") - 1, 0);
3275 ptr = ZSTR_VAL(*callable_name);
3276 memcpy(ptr, Z_STRVAL_P(obj), Z_STRLEN_P(obj));
3277 ptr += Z_STRLEN_P(obj);
3278 memcpy(ptr, "::", sizeof("::") - 1);
3279 ptr += sizeof("::") - 1;
3280 memcpy(ptr, Z_STRVAL_P(method), Z_STRLEN_P(method) + 1);
3281 }
3282
3283 if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
3284 return 1;
3285 }
3286
3287 if (!zend_is_callable_check_class(Z_STR_P(obj), fcc, &strict_class, error)) {
3288 return 0;
3289 }
3290
3291 } else if (Z_TYPE_P(obj) == IS_OBJECT) {
3292 if (!EG(objects_store).object_buckets ||
3293 !IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(obj)])) {
3294 return 0;
3295 }
3296
3297 fcc->calling_scope = Z_OBJCE_P(obj);
3298
3299 fcc->object = Z_OBJ_P(obj);
3300
3301 if (callable_name) {
3302 char *ptr;
3303
3304 *callable_name = zend_string_alloc(ZSTR_LEN(fcc->calling_scope->name) + Z_STRLEN_P(method) + sizeof("::") - 1, 0);
3305 ptr = ZSTR_VAL(*callable_name);
3306 memcpy(ptr, ZSTR_VAL(fcc->calling_scope->name), ZSTR_LEN(fcc->calling_scope->name));
3307 ptr += ZSTR_LEN(fcc->calling_scope->name);
3308 memcpy(ptr, "::", sizeof("::") - 1);
3309 ptr += sizeof("::") - 1;
3310 memcpy(ptr, Z_STRVAL_P(method), Z_STRLEN_P(method) + 1);
3311 }
3312
3313 if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
3314 fcc->called_scope = fcc->calling_scope;
3315 return 1;
3316 }
3317 } else {
3318 break;
3319 }
3320
3321 ret = zend_is_callable_check_func(check_flags, method, fcc, strict_class, error);
3322 if (fcc == &fcc_local &&
3323 fcc->function_handler &&
3324 ((fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) ||
3325 fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
3326 fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
3327 if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
3328 zend_string_release(fcc->function_handler->common.function_name);
3329 }
3330 zend_free_trampoline(fcc->function_handler);
3331 }
3332 return ret;
3333
3334 } while (0);
3335 if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
3336 if (!obj || (!Z_ISREF_P(obj)?
3337 (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) :
3338 (Z_TYPE_P(Z_REFVAL_P(obj)) != IS_STRING && Z_TYPE_P(Z_REFVAL_P(obj)) != IS_OBJECT))) {
3339 if (error) zend_spprintf(error, 0, "first array member is not a valid class name or object");
3340 } else {
3341 if (error) zend_spprintf(error, 0, "second array member is not a valid method");
3342 }
3343 } else {
3344 if (error) zend_spprintf(error, 0, "array must have exactly two members");
3345 }
3346 if (callable_name) {
3347 *callable_name = zend_string_init("Array", sizeof("Array")-1, 0);
3348 }
3349 }
3350 return 0;
3351 case IS_OBJECT:
3352 if (Z_OBJ_HANDLER_P(callable, get_closure) && Z_OBJ_HANDLER_P(callable, get_closure)(callable, &fcc->calling_scope, &fcc->function_handler, &fcc->object) == SUCCESS) {
3353 fcc->called_scope = fcc->calling_scope;
3354 if (callable_name) {
3355 zend_class_entry *ce = Z_OBJCE_P(callable);
3356
3357 *callable_name = zend_string_alloc(ZSTR_LEN(ce->name) + sizeof("::__invoke") - 1, 0);
3358 memcpy(ZSTR_VAL(*callable_name), ZSTR_VAL(ce->name), ZSTR_LEN(ce->name));
3359 memcpy(ZSTR_VAL(*callable_name) + ZSTR_LEN(ce->name), "::__invoke", sizeof("::__invoke"));
3360 }
3361 return 1;
3362 }
3363 if (callable_name) {
3364 *callable_name = zval_get_string(callable);
3365 }
3366 if (error) zend_spprintf(error, 0, "no array or string given");
3367 return 0;
3368 case IS_REFERENCE:
3369 callable = Z_REFVAL_P(callable);
3370 goto again;
3371 default:
3372 if (callable_name) {
3373 *callable_name = zval_get_string(callable);
3374 }
3375 if (error) zend_spprintf(error, 0, "no array or string given");
3376 return 0;
3377 }
3378 }
3379
3380
3381 ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, zend_string **callable_name)
3382 {
3383 return zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, NULL);
3384 }
3385
3386
3387 ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_name)
3388 {
3389 zend_fcall_info_cache fcc;
3390
3391 if (zend_is_callable_ex(callable, NULL, IS_CALLABLE_STRICT, callable_name, &fcc, NULL)) {
3392 if (Z_TYPE_P(callable) == IS_STRING && fcc.calling_scope) {
3393 zval_dtor(callable);
3394 array_init(callable);
3395 add_next_index_str(callable, zend_string_copy(fcc.calling_scope->name));
3396 add_next_index_str(callable, zend_string_copy(fcc.function_handler->common.function_name));
3397 }
3398 if (fcc.function_handler &&
3399 ((fcc.function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) ||
3400 fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
3401 fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
3402 if (fcc.function_handler->type != ZEND_OVERLOADED_FUNCTION) {
3403 zend_string_release(fcc.function_handler->common.function_name);
3404 }
3405 zend_free_trampoline(fcc.function_handler);
3406 }
3407 return 1;
3408 }
3409 return 0;
3410 }
3411
3412
3413 ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error)
3414 {
3415 if (!zend_is_callable_ex(callable, NULL, check_flags, callable_name, fcc, error)) {
3416 return FAILURE;
3417 }
3418
3419 fci->size = sizeof(*fci);
3420 fci->function_table = fcc->calling_scope ? &fcc->calling_scope->function_table : EG(function_table);
3421 fci->object = fcc->object;
3422 ZVAL_COPY_VALUE(&fci->function_name, callable);
3423 fci->retval = NULL;
3424 fci->param_count = 0;
3425 fci->params = NULL;
3426 fci->no_separation = 1;
3427 fci->symbol_table = NULL;
3428
3429 return SUCCESS;
3430 }
3431
3432
3433 ZEND_API void zend_fcall_info_args_clear(zend_fcall_info *fci, int free_mem)
3434 {
3435 if (fci->params) {
3436 zval *p = fci->params;
3437 zval *end = p + fci->param_count;
3438
3439 while (p != end) {
3440 i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
3441 p++;
3442 }
3443 if (free_mem) {
3444 efree(fci->params);
3445 fci->params = NULL;
3446 }
3447 }
3448 fci->param_count = 0;
3449 }
3450
3451
3452 ZEND_API void zend_fcall_info_args_save(zend_fcall_info *fci, int *param_count, zval **params)
3453 {
3454 *param_count = fci->param_count;
3455 *params = fci->params;
3456 fci->param_count = 0;
3457 fci->params = NULL;
3458 }
3459
3460
3461 ZEND_API void zend_fcall_info_args_restore(zend_fcall_info *fci, int param_count, zval *params)
3462 {
3463 zend_fcall_info_args_clear(fci, 1);
3464 fci->param_count = param_count;
3465 fci->params = params;
3466 }
3467
3468
3469 ZEND_API int zend_fcall_info_args_ex(zend_fcall_info *fci, zend_function *func, zval *args)
3470 {
3471 zval *arg, *params;
3472 uint32_t n = 1;
3473
3474 zend_fcall_info_args_clear(fci, !args);
3475
3476 if (!args) {
3477 return SUCCESS;
3478 }
3479
3480 if (Z_TYPE_P(args) != IS_ARRAY) {
3481 return FAILURE;
3482 }
3483
3484 fci->param_count = zend_hash_num_elements(Z_ARRVAL_P(args));
3485 fci->params = params = (zval *) erealloc(fci->params, fci->param_count * sizeof(zval));
3486
3487 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), arg) {
3488 if (func && !Z_ISREF_P(arg) && ARG_SHOULD_BE_SENT_BY_REF(func, n)) {
3489 ZVAL_NEW_REF(params, arg);
3490 if (Z_REFCOUNTED_P(arg)) {
3491 Z_ADDREF_P(arg);
3492 }
3493 } else {
3494 ZVAL_COPY(params, arg);
3495 }
3496 params++;
3497 n++;
3498 } ZEND_HASH_FOREACH_END();
3499
3500 return SUCCESS;
3501 }
3502
3503
3504 ZEND_API int zend_fcall_info_args(zend_fcall_info *fci, zval *args)
3505 {
3506 return zend_fcall_info_args_ex(fci, NULL, args);
3507 }
3508
3509
3510 ZEND_API int zend_fcall_info_argp(zend_fcall_info *fci, int argc, zval *argv)
3511 {
3512 int i;
3513
3514 if (argc < 0) {
3515 return FAILURE;
3516 }
3517
3518 zend_fcall_info_args_clear(fci, !argc);
3519
3520 if (argc) {
3521 fci->param_count = argc;
3522 fci->params = (zval *) erealloc(fci->params, fci->param_count * sizeof(zval));
3523
3524 for (i = 0; i < argc; ++i) {
3525 ZVAL_COPY(&fci->params[i], &argv[i]);
3526 }
3527 }
3528
3529 return SUCCESS;
3530 }
3531
3532
3533 ZEND_API int zend_fcall_info_argv(zend_fcall_info *fci, int argc, va_list *argv)
3534 {
3535 int i;
3536 zval *arg;
3537
3538 if (argc < 0) {
3539 return FAILURE;
3540 }
3541
3542 zend_fcall_info_args_clear(fci, !argc);
3543
3544 if (argc) {
3545 fci->param_count = argc;
3546 fci->params = (zval *) erealloc(fci->params, fci->param_count * sizeof(zval));
3547
3548 for (i = 0; i < argc; ++i) {
3549 arg = va_arg(*argv, zval *);
3550 ZVAL_COPY(&fci->params[i], arg);
3551 }
3552 }
3553
3554 return SUCCESS;
3555 }
3556
3557
3558 ZEND_API int zend_fcall_info_argn(zend_fcall_info *fci, int argc, ...)
3559 {
3560 int ret;
3561 va_list argv;
3562
3563 va_start(argv, argc);
3564 ret = zend_fcall_info_argv(fci, argc, &argv);
3565 va_end(argv);
3566
3567 return ret;
3568 }
3569
3570
3571 ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *retval_ptr, zval *args)
3572 {
3573 zval retval, *org_params = NULL;
3574 int result, org_count = 0;
3575
3576 fci->retval = retval_ptr ? retval_ptr : &retval;
3577 if (args) {
3578 zend_fcall_info_args_save(fci, &org_count, &org_params);
3579 zend_fcall_info_args(fci, args);
3580 }
3581 result = zend_call_function(fci, fcc);
3582
3583 if (!retval_ptr && Z_TYPE(retval) != IS_UNDEF) {
3584 zval_ptr_dtor(&retval);
3585 }
3586 if (args) {
3587 zend_fcall_info_args_restore(fci, org_count, org_params);
3588 }
3589 return result;
3590 }
3591
3592
3593 ZEND_API const char *zend_get_module_version(const char *module_name)
3594 {
3595 zend_string *lname;
3596 size_t name_len = strlen(module_name);
3597 zend_module_entry *module;
3598
3599 lname = zend_string_alloc(name_len, 0);
3600 zend_str_tolower_copy(ZSTR_VAL(lname), module_name, name_len);
3601 module = zend_hash_find_ptr(&module_registry, lname);
3602 zend_string_free(lname);
3603 return module ? module->version : NULL;
3604 }
3605
3606
3607 ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment)
3608 {
3609 zend_property_info *property_info, *property_info_ptr;
3610
3611 if (ce->type == ZEND_INTERNAL_CLASS) {
3612 property_info = pemalloc(sizeof(zend_property_info), 1);
3613 if ((access_type & ZEND_ACC_STATIC) || Z_CONSTANT_P(property)) {
3614 ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
3615 }
3616 } else {
3617 property_info = zend_arena_alloc(&CG(arena), sizeof(zend_property_info));
3618 if (Z_CONSTANT_P(property)) {
3619 ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
3620 }
3621 }
3622
3623 if (!(access_type & ZEND_ACC_PPP_MASK)) {
3624 access_type |= ZEND_ACC_PUBLIC;
3625 }
3626 if (access_type & ZEND_ACC_STATIC) {
3627 if ((property_info_ptr = zend_hash_find_ptr(&ce->properties_info, name)) != NULL &&
3628 (property_info_ptr->flags & ZEND_ACC_STATIC) != 0) {
3629 property_info->offset = property_info_ptr->offset;
3630 zval_ptr_dtor(&ce->default_static_members_table[property_info->offset]);
3631 zend_hash_del(&ce->properties_info, name);
3632 } else {
3633 property_info->offset = ce->default_static_members_count++;
3634 ce->default_static_members_table = perealloc(ce->default_static_members_table, sizeof(zval) * ce->default_static_members_count, ce->type == ZEND_INTERNAL_CLASS);
3635 }
3636 ZVAL_COPY_VALUE(&ce->default_static_members_table[property_info->offset], property);
3637 if (ce->type == ZEND_USER_CLASS) {
3638 ce->static_members_table = ce->default_static_members_table;
3639 }
3640 } else {
3641 if ((property_info_ptr = zend_hash_find_ptr(&ce->properties_info, name)) != NULL &&
3642 (property_info_ptr->flags & ZEND_ACC_STATIC) == 0) {
3643 property_info->offset = property_info_ptr->offset;
3644 zval_ptr_dtor(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]);
3645 zend_hash_del(&ce->properties_info, name);
3646 } else {
3647 property_info->offset = OBJ_PROP_TO_OFFSET(ce->default_properties_count);
3648 ce->default_properties_count++;
3649 ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(zval) * ce->default_properties_count, ce->type == ZEND_INTERNAL_CLASS);
3650 }
3651 ZVAL_COPY_VALUE(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)], property);
3652 }
3653 if (ce->type & ZEND_INTERNAL_CLASS) {
3654 switch(Z_TYPE_P(property)) {
3655 case IS_ARRAY:
3656 case IS_OBJECT:
3657 case IS_RESOURCE:
3658 zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
3659 break;
3660 default:
3661 break;
3662 }
3663 }
3664 if (access_type & ZEND_ACC_PUBLIC) {
3665 property_info->name = zend_string_copy(name);
3666 } else if (access_type & ZEND_ACC_PRIVATE) {
3667 property_info->name = zend_mangle_property_name(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
3668 } else {
3669 ZEND_ASSERT(access_type & ZEND_ACC_PROTECTED);
3670 property_info->name = zend_mangle_property_name("*", 1, ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
3671 }
3672
3673 property_info->name = zend_new_interned_string(property_info->name);
3674 property_info->flags = access_type;
3675 property_info->doc_comment = doc_comment;
3676 property_info->ce = ce;
3677 zend_hash_update_ptr(&ce->properties_info, name, property_info);
3678
3679 return SUCCESS;
3680 }
3681
3682
3683 ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type)
3684 {
3685 zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS);
3686 int ret = zend_declare_property_ex(ce, key, property, access_type, NULL);
3687 zend_string_release(key);
3688 return ret;
3689 }
3690
3691
3692 ZEND_API int zend_declare_property_null(zend_class_entry *ce, const char *name, size_t name_length, int access_type)
3693 {
3694 zval property;
3695
3696 ZVAL_NULL(&property);
3697 return zend_declare_property(ce, name, name_length, &property, access_type);
3698 }
3699
3700
3701 ZEND_API int zend_declare_property_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type)
3702 {
3703 zval property;
3704
3705 ZVAL_BOOL(&property, value);
3706 return zend_declare_property(ce, name, name_length, &property, access_type);
3707 }
3708
3709
3710 ZEND_API int zend_declare_property_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type)
3711 {
3712 zval property;
3713
3714 ZVAL_LONG(&property, value);
3715 return zend_declare_property(ce, name, name_length, &property, access_type);
3716 }
3717
3718
3719 ZEND_API int zend_declare_property_double(zend_class_entry *ce, const char *name, size_t name_length, double value, int access_type)
3720 {
3721 zval property;
3722
3723 ZVAL_DOUBLE(&property, value);
3724 return zend_declare_property(ce, name, name_length, &property, access_type);
3725 }
3726
3727
3728 ZEND_API int zend_declare_property_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value, int access_type)
3729 {
3730 zval property;
3731
3732 ZVAL_NEW_STR(&property, zend_string_init(value, strlen(value), ce->type & ZEND_INTERNAL_CLASS));
3733 return zend_declare_property(ce, name, name_length, &property, access_type);
3734 }
3735
3736
3737 ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_len, int access_type)
3738 {
3739 zval property;
3740
3741 ZVAL_NEW_STR(&property, zend_string_init(value, value_len, ce->type & ZEND_INTERNAL_CLASS));
3742 return zend_declare_property(ce, name, name_length, &property, access_type);
3743 }
3744
3745
3746 ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value)
3747 {
3748 if (Z_CONSTANT_P(value)) {
3749 ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
3750 }
3751 return zend_hash_str_update(&ce->constants_table, name, name_length, value) ?
3752 SUCCESS : FAILURE;
3753 }
3754
3755
3756 ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, const char *name, size_t name_length)
3757 {
3758 zval constant;
3759
3760 ZVAL_NULL(&constant);
3761 return zend_declare_class_constant(ce, name, name_length, &constant);
3762 }
3763
3764
3765 ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value)
3766 {
3767 zval constant;
3768
3769 ZVAL_LONG(&constant, value);
3770 return zend_declare_class_constant(ce, name, name_length, &constant);
3771 }
3772
3773
3774 ZEND_API int zend_declare_class_constant_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_bool value)
3775 {
3776 zval constant;
3777
3778 ZVAL_BOOL(&constant, value);
3779 return zend_declare_class_constant(ce, name, name_length, &constant);
3780 }
3781
3782
3783 ZEND_API int zend_declare_class_constant_double(zend_class_entry *ce, const char *name, size_t name_length, double value)
3784 {
3785 zval constant;
3786
3787 ZVAL_DOUBLE(&constant, value);
3788 return zend_declare_class_constant(ce, name, name_length, &constant);
3789 }
3790
3791
3792 ZEND_API int zend_declare_class_constant_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_length)
3793 {
3794 zval constant;
3795
3796 ZVAL_NEW_STR(&constant, zend_string_init(value, value_length, ce->type & ZEND_INTERNAL_CLASS));
3797 return zend_declare_class_constant(ce, name, name_length, &constant);
3798 }
3799
3800
3801 ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value)
3802 {
3803 return zend_declare_class_constant_stringl(ce, name, name_length, value, strlen(value));
3804 }
3805
3806
3807 ZEND_API void zend_update_property_ex(zend_class_entry *scope, zval *object, zend_string *name, zval *value)
3808 {
3809 zval property;
3810 zend_class_entry *old_scope = EG(scope);
3811
3812 EG(scope) = scope;
3813
3814 if (!Z_OBJ_HT_P(object)->write_property) {
3815 zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, ZSTR_VAL(Z_OBJCE_P(object)->name));
3816 }
3817 ZVAL_STR(&property, name);
3818 Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL);
3819
3820 EG(scope) = old_scope;
3821 }
3822
3823
3824 ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zval *value)
3825 {
3826 zval property;
3827 zend_class_entry *old_scope = EG(scope);
3828
3829 EG(scope) = scope;
3830
3831 if (!Z_OBJ_HT_P(object)->write_property) {
3832 zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, ZSTR_VAL(Z_OBJCE_P(object)->name));
3833 }
3834 ZVAL_STRINGL(&property, name, name_length);
3835 Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL);
3836 zval_ptr_dtor(&property);
3837
3838 EG(scope) = old_scope;
3839 }
3840
3841
3842 ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, size_t name_length)
3843 {
3844 zval tmp;
3845
3846 ZVAL_NULL(&tmp);
3847 zend_update_property(scope, object, name, name_length, &tmp);
3848 }
3849
3850
3851 ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value)
3852 {
3853 zval tmp;
3854
3855 ZVAL_BOOL(&tmp, value);
3856 zend_update_property(scope, object, name, name_length, &tmp);
3857 }
3858
3859
3860 ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value)
3861 {
3862 zval tmp;
3863
3864 ZVAL_LONG(&tmp, value);
3865 zend_update_property(scope, object, name, name_length, &tmp);
3866 }
3867
3868
3869 ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, const char *name, size_t name_length, double value)
3870 {
3871 zval tmp;
3872
3873 ZVAL_DOUBLE(&tmp, value);
3874 zend_update_property(scope, object, name, name_length, &tmp);
3875 }
3876
3877
3878 ZEND_API void zend_update_property_str(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_string *value)
3879 {
3880 zval tmp;
3881
3882 ZVAL_STR(&tmp, value);
3883 zend_update_property(scope, object, name, name_length, &tmp);
3884 }
3885
3886
3887 ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value)
3888 {
3889 zval tmp;
3890
3891 ZVAL_STRING(&tmp, value);
3892 Z_SET_REFCOUNT(tmp, 0);
3893 zend_update_property(scope, object, name, name_length, &tmp);
3894 }
3895
3896
3897 ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value, size_t value_len)
3898 {
3899 zval tmp;
3900
3901 ZVAL_STRINGL(&tmp, value, value_len);
3902 Z_SET_REFCOUNT(tmp, 0);
3903 zend_update_property(scope, object, name, name_length, &tmp);
3904 }
3905
3906
3907 ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, size_t name_length, zval *value)
3908 {
3909 zval *property;
3910 zend_class_entry *old_scope = EG(scope);
3911 zend_string *key = zend_string_init(name, name_length, 0);
3912
3913 EG(scope) = scope;
3914 property = zend_std_get_static_property(scope, key, 0);
3915 EG(scope) = old_scope;
3916 zend_string_free(key);
3917 if (!property) {
3918 return FAILURE;
3919 } else {
3920 if (property != value) {
3921 if (Z_ISREF_P(property)) {
3922 zval_dtor(property);
3923 ZVAL_COPY_VALUE(property, value);
3924 if (Z_REFCOUNTED_P(value) && Z_REFCOUNT_P(value) > 0) {
3925 zval_opt_copy_ctor(property);
3926 }
3927 } else {
3928 zval garbage;
3929
3930 ZVAL_COPY_VALUE(&garbage, property);
3931 if (Z_REFCOUNTED_P(value)) {
3932 Z_ADDREF_P(value);
3933 if (Z_ISREF_P(value)) {
3934 SEPARATE_ZVAL(value);
3935 }
3936 }
3937 ZVAL_COPY_VALUE(property, value);
3938 zval_ptr_dtor(&garbage);
3939 }
3940 }
3941 return SUCCESS;
3942 }
3943 }
3944
3945
3946 ZEND_API int zend_update_static_property_null(zend_class_entry *scope, const char *name, size_t name_length)
3947 {
3948 zval tmp;
3949
3950 ZVAL_NULL(&tmp);
3951 return zend_update_static_property(scope, name, name_length, &tmp);
3952 }
3953
3954
3955 ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, const char *name, size_t name_length, zend_long value)
3956 {
3957 zval tmp;
3958
3959 ZVAL_BOOL(&tmp, value);
3960 return zend_update_static_property(scope, name, name_length, &tmp);
3961 }
3962
3963
3964 ZEND_API int zend_update_static_property_long(zend_class_entry *scope, const char *name, size_t name_length, zend_long value)
3965 {
3966 zval tmp;
3967
3968 ZVAL_LONG(&tmp, value);
3969 return zend_update_static_property(scope, name, name_length, &tmp);
3970 }
3971
3972
3973 ZEND_API int zend_update_static_property_double(zend_class_entry *scope, const char *name, size_t name_length, double value)
3974 {
3975 zval tmp;
3976
3977 ZVAL_DOUBLE(&tmp, value);
3978 return zend_update_static_property(scope, name, name_length, &tmp);
3979 }
3980
3981
3982 ZEND_API int zend_update_static_property_string(zend_class_entry *scope, const char *name, size_t name_length, const char *value)
3983 {
3984 zval tmp;
3985
3986 ZVAL_STRING(&tmp, value);
3987 Z_SET_REFCOUNT(tmp, 0);
3988 return zend_update_static_property(scope, name, name_length, &tmp);
3989 }
3990
3991
3992 ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const char *name, size_t name_length, const char *value, size_t value_len)
3993 {
3994 zval tmp;
3995
3996 ZVAL_STRINGL(&tmp, value, value_len);
3997 Z_SET_REFCOUNT(tmp, 0);
3998 return zend_update_static_property(scope, name, name_length, &tmp);
3999 }
4000
4001
4002 ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent, zval *rv)
4003 {
4004 zval property, *value;
4005 zend_class_entry *old_scope = EG(scope);
4006
4007 EG(scope) = scope;
4008
4009 if (!Z_OBJ_HT_P(object)->read_property) {
4010 zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be read", name, ZSTR_VAL(Z_OBJCE_P(object)->name));
4011 }
4012
4013 ZVAL_STRINGL(&property, name, name_length);
4014 value = Z_OBJ_HT_P(object)->read_property(object, &property, silent?BP_VAR_IS:BP_VAR_R, NULL, rv);
4015 zval_ptr_dtor(&property);
4016
4017 EG(scope) = old_scope;
4018 return value;
4019 }
4020
4021
4022 ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent)
4023 {
4024 zval *property;
4025 zend_class_entry *old_scope = EG(scope);
4026 zend_string *key = zend_string_init(name, name_length, 0);
4027
4028 EG(scope) = scope;
4029 property = zend_std_get_static_property(scope, key, silent);
4030 EG(scope) = old_scope;
4031 zend_string_free(key);
4032
4033 return property;
4034 }
4035
4036
4037 ZEND_API void zend_save_error_handling(zend_error_handling *current)
4038 {
4039 current->handling = EG(error_handling);
4040 current->exception = EG(exception_class);
4041 ZVAL_COPY(¤t->user_handler, &EG(user_error_handler));
4042 }
4043
4044
4045 ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current)
4046 {
4047 if (current) {
4048 zend_save_error_handling(current);
4049 if (error_handling != EH_NORMAL && Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
4050 zval_ptr_dtor(&EG(user_error_handler));
4051 ZVAL_UNDEF(&EG(user_error_handler));
4052 }
4053 }
4054 EG(error_handling) = error_handling;
4055 EG(exception_class) = error_handling == EH_THROW ? exception_class : NULL;
4056 }
4057
4058
4059 static int same_zval(zval *zv1, zval *zv2)
4060 {
4061 if (Z_TYPE_P(zv1) != Z_TYPE_P(zv2)) {
4062 return 0;
4063 }
4064 switch (Z_TYPE_P(zv1)) {
4065 case IS_UNDEF:
4066 case IS_NULL:
4067 case IS_FALSE:
4068 case IS_TRUE:
4069 return 1;
4070 case IS_LONG:
4071 return Z_LVAL_P(zv1) == Z_LVAL_P(zv2);
4072 case IS_DOUBLE:
4073 return Z_LVAL_P(zv1) == Z_LVAL_P(zv2);
4074 case IS_STRING:
4075 case IS_ARRAY:
4076 case IS_OBJECT:
4077 case IS_RESOURCE:
4078 return Z_COUNTED_P(zv1) == Z_COUNTED_P(zv2);
4079 default:
4080 return 0;
4081 }
4082 }
4083
4084
4085 ZEND_API void zend_restore_error_handling(zend_error_handling *saved)
4086 {
4087 EG(error_handling) = saved->handling;
4088 EG(exception_class) = saved->handling == EH_THROW ? saved->exception : NULL;
4089 if (Z_TYPE(saved->user_handler) != IS_UNDEF
4090 && !same_zval(&saved->user_handler, &EG(user_error_handler))) {
4091 zval_ptr_dtor(&EG(user_error_handler));
4092 ZVAL_COPY_VALUE(&EG(user_error_handler), &saved->user_handler);
4093 } else if (Z_TYPE(saved->user_handler)) {
4094 zval_ptr_dtor(&saved->user_handler);
4095 }
4096 ZVAL_UNDEF(&saved->user_handler);
4097 }
4098
4099
4100 ZEND_API zend_string* zend_find_alias_name(zend_class_entry *ce, zend_string *name)
4101 {
4102 zend_trait_alias *alias, **alias_ptr;
4103
4104 if ((alias_ptr = ce->trait_aliases)) {
4105 alias = *alias_ptr;
4106 while (alias) {
4107 if (alias->alias && zend_string_equals_ci(alias->alias, name)) {
4108 return alias->alias;
4109 }
4110 alias_ptr++;
4111 alias = *alias_ptr;
4112 }
4113 }
4114
4115 return name;
4116 }
4117
4118
4119 ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_function *f)
4120 {
4121 zend_function *func;
4122 HashTable *function_table;
4123 zend_string *name;
4124
4125 if (f->common.type != ZEND_USER_FUNCTION ||
4126 (f->op_array.refcount && *(f->op_array.refcount) < 2) ||
4127 !f->common.scope ||
4128 !f->common.scope->trait_aliases) {
4129 return f->common.function_name;
4130 }
4131
4132 function_table = &ce->function_table;
4133 ZEND_HASH_FOREACH_STR_KEY_PTR(function_table, name, func) {
4134 if (func == f) {
4135 if (!name) {
4136 return f->common.function_name;
4137 }
4138 if (ZSTR_LEN(name) == ZSTR_LEN(f->common.function_name) &&
4139 !strncasecmp(ZSTR_VAL(name), ZSTR_VAL(f->common.function_name), ZSTR_LEN(f->common.function_name))) {
4140 return f->common.function_name;
4141 }
4142 return zend_find_alias_name(f->common.scope, name);
4143 }
4144 } ZEND_HASH_FOREACH_END();
4145 return f->common.function_name;
4146 }
4147
4148
4149 ZEND_API const char *zend_get_object_type(const zend_class_entry *ce)
4150 {
4151 if(ce->ce_flags & ZEND_ACC_TRAIT) {
4152 return "trait";
4153 } else if (ce->ce_flags & ZEND_ACC_INTERFACE) {
4154 return "interface";
4155 } else {
4156 return "class";
4157 }
4158 }
4159
4160
4161
4162
4163
4164
4165
4166
4167