1 : /*
2 : +----------------------------------------------------------------------+
3 : | Zend Engine |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1998-2009 Zend Technologies Ltd. (http://www.zend.com) |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 2.00 of the Zend license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.zend.com/license/2_00.txt. |
11 : | If you did not receive a copy of the Zend license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@zend.com so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Authors: Andi Gutmans <andi@zend.com> |
16 : | Zeev Suraski <zeev@zend.com> |
17 : | Andrei Zmievski <andrei@php.net> |
18 : +----------------------------------------------------------------------+
19 : */
20 :
21 : /* $Id: zend_API.c 288088 2009-09-05 19:00:05Z pajoye $ */
22 :
23 : #include "zend.h"
24 : #include "zend_execute.h"
25 : #include "zend_API.h"
26 : #include "zend_modules.h"
27 : #include "zend_constants.h"
28 : #include "zend_exceptions.h"
29 : #include "zend_closures.h"
30 :
31 : #ifdef HAVE_STDARG_H
32 : #include <stdarg.h>
33 : #endif
34 :
35 : /* these variables are true statics/globals, and have to be mutex'ed on every access */
36 : static int module_count=0;
37 : ZEND_API HashTable module_registry;
38 :
39 : /* this function doesn't check for too many parameters */
40 : ZEND_API int zend_get_parameters(int ht, int param_count, ...) /* {{{ */
41 0 : {
42 : void **p;
43 : int arg_count;
44 : va_list ptr;
45 : zval **param, *param_ptr;
46 : TSRMLS_FETCH();
47 :
48 0 : p = zend_vm_stack_top(TSRMLS_C) - 1;
49 0 : arg_count = (int)(zend_uintptr_t) *p;
50 :
51 0 : if (param_count>arg_count) {
52 0 : return FAILURE;
53 : }
54 :
55 0 : va_start(ptr, param_count);
56 :
57 0 : while (param_count-->0) {
58 0 : param = va_arg(ptr, zval **);
59 0 : param_ptr = *(p-arg_count);
60 0 : if (!PZVAL_IS_REF(param_ptr) && Z_REFCOUNT_P(param_ptr) > 1) {
61 : zval *new_tmp;
62 :
63 0 : ALLOC_ZVAL(new_tmp);
64 0 : *new_tmp = *param_ptr;
65 0 : zval_copy_ctor(new_tmp);
66 0 : INIT_PZVAL(new_tmp);
67 0 : param_ptr = new_tmp;
68 0 : Z_DELREF_P((zval *) *(p-arg_count));
69 0 : *(p-arg_count) = param_ptr;
70 : }
71 0 : *param = param_ptr;
72 0 : arg_count--;
73 : }
74 0 : va_end(ptr);
75 :
76 0 : return SUCCESS;
77 : }
78 : /* }}} */
79 :
80 : ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval **argument_array TSRMLS_DC) /* {{{ */
81 23 : {
82 : void **p;
83 : int arg_count;
84 : zval *param_ptr;
85 :
86 23 : p = zend_vm_stack_top(TSRMLS_C) - 1;
87 23 : arg_count = (int)(zend_uintptr_t) *p;
88 :
89 23 : if (param_count>arg_count) {
90 0 : return FAILURE;
91 : }
92 :
93 70 : while (param_count-->0) {
94 24 : param_ptr = *(p-arg_count);
95 24 : if (!PZVAL_IS_REF(param_ptr) && Z_REFCOUNT_P(param_ptr) > 1) {
96 : zval *new_tmp;
97 :
98 1 : ALLOC_ZVAL(new_tmp);
99 1 : *new_tmp = *param_ptr;
100 1 : zval_copy_ctor(new_tmp);
101 1 : INIT_PZVAL(new_tmp);
102 1 : param_ptr = new_tmp;
103 1 : Z_DELREF_P((zval *) *(p-arg_count));
104 1 : *(p-arg_count) = param_ptr;
105 : }
106 24 : *(argument_array++) = param_ptr;
107 24 : arg_count--;
108 : }
109 :
110 23 : return SUCCESS;
111 : }
112 : /* }}} */
113 :
114 : /* Zend-optimized Extended functions */
115 : /* this function doesn't check for too many parameters */
116 : ZEND_API int zend_get_parameters_ex(int param_count, ...) /* {{{ */
117 0 : {
118 : void **p;
119 : int arg_count;
120 : va_list ptr;
121 : zval ***param;
122 : TSRMLS_FETCH();
123 :
124 0 : p = zend_vm_stack_top(TSRMLS_C) - 1;
125 0 : arg_count = (int)(zend_uintptr_t) *p;
126 :
127 0 : if (param_count>arg_count) {
128 0 : return FAILURE;
129 : }
130 :
131 0 : va_start(ptr, param_count);
132 0 : while (param_count-->0) {
133 0 : param = va_arg(ptr, zval ***);
134 0 : *param = (zval **) p-(arg_count--);
135 : }
136 0 : va_end(ptr);
137 :
138 0 : return SUCCESS;
139 : }
140 : /* }}} */
141 :
142 : ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_array TSRMLS_DC) /* {{{ */
143 22445 : {
144 : void **p;
145 : int arg_count;
146 :
147 22445 : p = zend_vm_stack_top(TSRMLS_C) - 1;
148 22445 : arg_count = (int)(zend_uintptr_t) *p;
149 :
150 22445 : if (param_count>arg_count) {
151 0 : return FAILURE;
152 : }
153 :
154 135724 : while (param_count-->0) {
155 90834 : zval **value = (zval**)(p-arg_count);
156 :
157 90834 : *(argument_array++) = value;
158 90834 : arg_count--;
159 : }
160 :
161 22445 : return SUCCESS;
162 : }
163 : /* }}} */
164 :
165 : ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TSRMLS_DC) /* {{{ */
166 455 : {
167 : void **p;
168 : int arg_count;
169 :
170 455 : p = zend_vm_stack_top(TSRMLS_C) - 1;
171 455 : arg_count = (int)(zend_uintptr_t) *p;
172 :
173 455 : if (param_count>arg_count) {
174 0 : return FAILURE;
175 : }
176 :
177 1352 : while (param_count-->0) {
178 442 : zval **param = (zval **) p-(arg_count--);
179 442 : zval_add_ref(param);
180 442 : add_next_index_zval(argument_array, *param);
181 : }
182 :
183 455 : return SUCCESS;
184 : }
185 : /* }}} */
186 :
187 : ZEND_API void zend_wrong_param_count(TSRMLS_D) /* {{{ */
188 32 : {
189 : char *space;
190 32 : char *class_name = get_active_class_name(&space TSRMLS_CC);
191 :
192 32 : zend_error(E_WARNING, "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name(TSRMLS_C));
193 32 : }
194 : /* }}} */
195 :
196 : /* Argument parsing API -- andrei */
197 : ZEND_API char *zend_get_type_by_const(int type) /* {{{ */
198 7703 : {
199 7703 : switch(type) {
200 : case IS_BOOL:
201 612 : return "boolean";
202 : case IS_LONG:
203 639 : return "integer";
204 : case IS_DOUBLE:
205 622 : return "double";
206 : case IS_STRING:
207 2025 : return "string";
208 : case IS_OBJECT:
209 705 : return "object";
210 : case IS_RESOURCE:
211 439 : return "resource";
212 : case IS_NULL:
213 600 : return "null";
214 : case IS_ARRAY:
215 2061 : return "array";
216 : default:
217 0 : return "unknown";
218 : }
219 : }
220 : /* }}} */
221 :
222 : ZEND_API char *zend_zval_type_name(const zval *arg) /* {{{ */
223 7686 : {
224 7686 : return zend_get_type_by_const(Z_TYPE_P(arg));
225 : }
226 : /* }}} */
227 :
228 : ZEND_API zend_class_entry *zend_get_class_entry(const zval *zobject TSRMLS_DC) /* {{{ */
229 632125 : {
230 632125 : if (Z_OBJ_HT_P(zobject)->get_class_entry) {
231 632125 : return Z_OBJ_HT_P(zobject)->get_class_entry(zobject TSRMLS_CC);
232 : } else {
233 0 : zend_error(E_ERROR, "Class entry requested for an object without PHP class");
234 0 : return NULL;
235 : }
236 : }
237 : /* }}} */
238 :
239 : /* returns 1 if you need to copy result, 0 if it's already a copy */
240 : ZEND_API int zend_get_object_classname(const zval *object, char **class_name, zend_uint *class_name_len TSRMLS_DC) /* {{{ */
241 522 : {
242 522 : if (Z_OBJ_HT_P(object)->get_class_name == NULL ||
243 : Z_OBJ_HT_P(object)->get_class_name(object, class_name, class_name_len, 0 TSRMLS_CC) != SUCCESS) {
244 0 : zend_class_entry *ce = Z_OBJCE_P(object);
245 :
246 0 : *class_name = ce->name;
247 0 : *class_name_len = ce->name_length;
248 0 : return 1;
249 : }
250 522 : return 0;
251 : }
252 : /* }}} */
253 :
254 : static int parse_arg_object_to_string(zval **arg, char **p, int *pl, int type TSRMLS_DC) /* {{{ */
255 200476 : {
256 200476 : if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
257 200476 : SEPARATE_ZVAL_IF_NOT_REF(arg);
258 200476 : if (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, type TSRMLS_CC) == SUCCESS) {
259 200305 : *pl = Z_STRLEN_PP(arg);
260 200305 : *p = Z_STRVAL_PP(arg);
261 200305 : return SUCCESS;
262 : }
263 : }
264 : /* Standard PHP objects */
265 171 : if (Z_OBJ_HT_PP(arg) == &std_object_handlers || !Z_OBJ_HANDLER_PP(arg, cast_object)) {
266 169 : SEPARATE_ZVAL_IF_NOT_REF(arg);
267 169 : if (zend_std_cast_object_tostring(*arg, *arg, type TSRMLS_CC) == SUCCESS) {
268 0 : *pl = Z_STRLEN_PP(arg);
269 0 : *p = Z_STRVAL_PP(arg);
270 0 : return SUCCESS;
271 : }
272 : }
273 171 : if (!Z_OBJ_HANDLER_PP(arg, cast_object) && Z_OBJ_HANDLER_PP(arg, get)) {
274 : int use_copy;
275 0 : zval *z = Z_OBJ_HANDLER_PP(arg, get)(*arg TSRMLS_CC);
276 0 : Z_ADDREF_P(z);
277 0 : if(Z_TYPE_P(z) != IS_OBJECT) {
278 0 : zval_dtor(*arg);
279 0 : Z_TYPE_P(*arg) = IS_NULL;
280 0 : zend_make_printable_zval(z, *arg, &use_copy);
281 0 : if (!use_copy) {
282 0 : ZVAL_ZVAL(*arg, z, 1, 1);
283 : }
284 0 : *pl = Z_STRLEN_PP(arg);
285 0 : *p = Z_STRVAL_PP(arg);
286 0 : return SUCCESS;
287 : }
288 0 : zval_ptr_dtor(&z);
289 : }
290 171 : return FAILURE;
291 : }
292 : /* }}} */
293 :
294 : static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **spec, char **error, int *severity TSRMLS_DC) /* {{{ */
295 25839977 : {
296 25839977 : char *spec_walk = *spec;
297 25839977 : char c = *spec_walk++;
298 25839977 : int return_null = 0;
299 :
300 : /* scan through modifiers */
301 : while (1) {
302 29003098 : if (*spec_walk == '/') {
303 237635 : SEPARATE_ZVAL_IF_NOT_REF(arg);
304 28765463 : } else if (*spec_walk == '!') {
305 2925486 : if (Z_TYPE_PP(arg) == IS_NULL) {
306 1425873 : return_null = 1;
307 : }
308 : } else {
309 25839977 : break;
310 : }
311 3163121 : spec_walk++;
312 3163121 : }
313 :
314 25839977 : switch (c) {
315 : case 'l':
316 : case 'L':
317 : {
318 5269273 : long *p = va_arg(*va, long *);
319 5269273 : switch (Z_TYPE_PP(arg)) {
320 : case IS_STRING:
321 : {
322 : double d;
323 : int type;
324 :
325 1970 : if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), p, &d, -1)) == 0) {
326 1248 : return "long";
327 722 : } else if (type == IS_DOUBLE) {
328 226 : if (c == 'L') {
329 0 : if (d > LONG_MAX) {
330 0 : *p = LONG_MAX;
331 0 : break;
332 0 : } else if (d < LONG_MIN) {
333 0 : *p = LONG_MIN;
334 0 : break;
335 : }
336 : }
337 :
338 226 : *p = zend_dval_to_lval(d);
339 : }
340 : }
341 722 : break;
342 :
343 : case IS_DOUBLE:
344 6575 : if (c == 'L') {
345 0 : if (Z_DVAL_PP(arg) > LONG_MAX) {
346 0 : *p = LONG_MAX;
347 0 : break;
348 0 : } else if (Z_DVAL_PP(arg) < LONG_MIN) {
349 0 : *p = LONG_MIN;
350 0 : break;
351 : }
352 : }
353 : case IS_NULL:
354 : case IS_LONG:
355 : case IS_BOOL:
356 5266347 : convert_to_long_ex(arg);
357 5266347 : *p = Z_LVAL_PP(arg);
358 5266347 : break;
359 :
360 : case IS_ARRAY:
361 : case IS_OBJECT:
362 : case IS_RESOURCE:
363 : default:
364 956 : return "long";
365 : }
366 : }
367 5267069 : break;
368 :
369 : case 'd':
370 : {
371 7745 : double *p = va_arg(*va, double *);
372 7745 : switch (Z_TYPE_PP(arg)) {
373 : case IS_STRING:
374 : {
375 : long l;
376 : int type;
377 :
378 630 : if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &l, p, -1)) == 0) {
379 247 : return "double";
380 383 : } else if (type == IS_LONG) {
381 169 : *p = (double) l;
382 : }
383 : }
384 383 : break;
385 :
386 : case IS_NULL:
387 : case IS_LONG:
388 : case IS_DOUBLE:
389 : case IS_BOOL:
390 6917 : convert_to_double_ex(arg);
391 6917 : *p = Z_DVAL_PP(arg);
392 6917 : break;
393 :
394 : case IS_ARRAY:
395 : case IS_OBJECT:
396 : case IS_RESOURCE:
397 : default:
398 198 : return "double";
399 : }
400 : }
401 7300 : break;
402 :
403 : case 's':
404 : {
405 9513803 : char **p = va_arg(*va, char **);
406 9513803 : int *pl = va_arg(*va, int *);
407 9513803 : switch (Z_TYPE_PP(arg)) {
408 : case IS_NULL:
409 5162 : if (return_null) {
410 823 : *p = NULL;
411 823 : *pl = 0;
412 823 : break;
413 : }
414 : /* break omitted intentionally */
415 :
416 : case IS_STRING:
417 : case IS_LONG:
418 : case IS_DOUBLE:
419 : case IS_BOOL:
420 9311251 : convert_to_string_ex(arg);
421 9311251 : *p = Z_STRVAL_PP(arg);
422 9311251 : *pl = Z_STRLEN_PP(arg);
423 9311251 : break;
424 :
425 : case IS_OBJECT:
426 200476 : if (parse_arg_object_to_string(arg, p, pl, IS_STRING TSRMLS_CC) == SUCCESS) {
427 200305 : break;
428 : }
429 :
430 : case IS_ARRAY:
431 : case IS_RESOURCE:
432 : default:
433 1424 : return "string";
434 : }
435 : }
436 9512379 : break;
437 :
438 : case 'b':
439 : {
440 15530 : zend_bool *p = va_arg(*va, zend_bool *);
441 15530 : switch (Z_TYPE_PP(arg)) {
442 : case IS_NULL:
443 : case IS_STRING:
444 : case IS_LONG:
445 : case IS_DOUBLE:
446 : case IS_BOOL:
447 15394 : convert_to_boolean_ex(arg);
448 15394 : *p = Z_BVAL_PP(arg);
449 : break;
450 :
451 : case IS_ARRAY:
452 : case IS_OBJECT:
453 : case IS_RESOURCE:
454 : default:
455 136 : return "boolean";
456 : }
457 : }
458 15394 : break;
459 :
460 : case 'r':
461 : {
462 3608779 : zval **p = va_arg(*va, zval **);
463 3608779 : if (return_null) {
464 106 : *p = NULL;
465 106 : break;
466 : }
467 3608673 : if (Z_TYPE_PP(arg) == IS_RESOURCE) {
468 3606953 : *p = *arg;
469 : } else {
470 1720 : return "resource";
471 : }
472 : }
473 3606953 : break;
474 : case 'A':
475 : case 'a':
476 : {
477 2320934 : zval **p = va_arg(*va, zval **);
478 2320934 : if (return_null) {
479 1424895 : *p = NULL;
480 1424895 : break;
481 : }
482 896039 : if (Z_TYPE_PP(arg) == IS_ARRAY || (c == 'A' && Z_TYPE_PP(arg) == IS_OBJECT)) {
483 894727 : *p = *arg;
484 : } else {
485 1312 : return "array";
486 : }
487 : }
488 894727 : break;
489 : case 'H':
490 : case 'h':
491 : {
492 79833 : HashTable **p = va_arg(*va, HashTable **);
493 79833 : if (return_null) {
494 0 : *p = NULL;
495 0 : break;
496 : }
497 79833 : if (Z_TYPE_PP(arg) == IS_ARRAY) {
498 79528 : *p = Z_ARRVAL_PP(arg);
499 333 : } else if(c == 'H' && Z_TYPE_PP(arg) == IS_OBJECT) {
500 28 : *p = HASH_OF(*arg);
501 28 : if(*p == NULL) {
502 0 : return "array";
503 : }
504 : } else {
505 277 : return "array";
506 : }
507 : }
508 79556 : break;
509 :
510 : case 'o':
511 : {
512 957 : zval **p = va_arg(*va, zval **);
513 957 : if (return_null) {
514 9 : *p = NULL;
515 9 : break;
516 : }
517 948 : if (Z_TYPE_PP(arg) == IS_OBJECT) {
518 834 : *p = *arg;
519 : } else {
520 114 : return "object";
521 : }
522 : }
523 834 : break;
524 :
525 : case 'O':
526 : {
527 104826 : zval **p = va_arg(*va, zval **);
528 104826 : zend_class_entry *ce = va_arg(*va, zend_class_entry *);
529 :
530 104826 : if (return_null) {
531 3 : *p = NULL;
532 3 : break;
533 : }
534 104823 : if (Z_TYPE_PP(arg) == IS_OBJECT &&
535 : (!ce || instanceof_function(Z_OBJCE_PP(arg), ce TSRMLS_CC))) {
536 104066 : *p = *arg;
537 : } else {
538 757 : if (ce) {
539 757 : return ce->name;
540 : } else {
541 0 : return "object";
542 : }
543 : }
544 : }
545 104066 : break;
546 :
547 : case 'C':
548 : {
549 31 : zend_class_entry **lookup, **pce = va_arg(*va, zend_class_entry **);
550 31 : zend_class_entry *ce_base = *pce;
551 :
552 31 : if (return_null) {
553 2 : *pce = NULL;
554 2 : break;
555 : }
556 29 : convert_to_string_ex(arg);
557 29 : if (zend_lookup_class(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &lookup TSRMLS_CC) == FAILURE) {
558 3 : *pce = NULL;
559 : } else {
560 26 : *pce = *lookup;
561 : }
562 29 : if (ce_base) {
563 29 : if ((!*pce || !instanceof_function(*pce, ce_base TSRMLS_CC))) {
564 9 : zend_spprintf(error, 0, "to be a class name derived from %s, '%s' given",
565 : ce_base->name, Z_STRVAL_PP(arg));
566 9 : *pce = NULL;
567 9 : return "";
568 : }
569 : }
570 20 : if (!*pce) {
571 0 : zend_spprintf(error, 0, "to be a valid class name, '%s' given",
572 : Z_STRVAL_PP(arg));
573 0 : return "";
574 : }
575 20 : break;
576 :
577 : }
578 : break;
579 :
580 : case 'f':
581 : {
582 3463 : zend_fcall_info *fci = va_arg(*va, zend_fcall_info *);
583 3463 : zend_fcall_info_cache *fcc = va_arg(*va, zend_fcall_info_cache *);
584 3463 : char *is_callable_error = NULL;
585 :
586 3463 : if (return_null) {
587 9 : fci->size = 0;
588 9 : fcc->initialized = 0;
589 9 : break;
590 : }
591 :
592 3454 : if (zend_fcall_info_init(*arg, 0, fci, fcc, NULL, &is_callable_error TSRMLS_CC) == SUCCESS) {
593 2723 : if (is_callable_error) {
594 4 : *severity = E_STRICT;
595 4 : zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error);
596 4 : efree(is_callable_error);
597 4 : *spec = spec_walk;
598 4 : return "";
599 : }
600 2719 : break;
601 : } else {
602 731 : if (is_callable_error) {
603 731 : *severity = E_WARNING;
604 731 : zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error);
605 731 : efree(is_callable_error);
606 731 : return "";
607 : } else {
608 0 : return "valid callback";
609 : }
610 : }
611 : }
612 :
613 : case 'z':
614 : {
615 2431497 : zval **p = va_arg(*va, zval **);
616 2431497 : if (return_null) {
617 15 : *p = NULL;
618 : } else {
619 2431482 : *p = *arg;
620 : }
621 : }
622 2431497 : break;
623 :
624 : case 'Z':
625 : {
626 2483306 : zval ***p = va_arg(*va, zval ***);
627 2483306 : if (return_null) {
628 11 : *p = NULL;
629 : } else {
630 2483295 : *p = arg;
631 : }
632 : }
633 2483306 : break;
634 :
635 : default:
636 0 : return "unknown";
637 : }
638 :
639 25830844 : *spec = spec_walk;
640 :
641 25830844 : return NULL;
642 : }
643 : /* }}} */
644 :
645 : static int zend_parse_arg(int arg_num, zval **arg, va_list *va, char **spec, int quiet TSRMLS_DC) /* {{{ */
646 25839977 : {
647 25839977 : char *expected_type = NULL, *error = NULL;
648 25839977 : int severity = E_WARNING;
649 :
650 25839977 : expected_type = zend_parse_arg_impl(arg_num, arg, va, spec, &error, &severity TSRMLS_CC);
651 25839977 : if (expected_type) {
652 9133 : if (!quiet && (*expected_type || error)) {
653 : char *space;
654 8352 : char *class_name = get_active_class_name(&space TSRMLS_CC);
655 :
656 8352 : if (error) {
657 744 : zend_error(severity, "%s%s%s() expects parameter %d %s",
658 : class_name, space, get_active_function_name(TSRMLS_C), arg_num, error);
659 744 : efree(error);
660 : } else {
661 7608 : zend_error(severity, "%s%s%s() expects parameter %d to be %s, %s given",
662 : class_name, space, get_active_function_name(TSRMLS_C), arg_num, expected_type,
663 : zend_zval_type_name(*arg));
664 : }
665 : }
666 9133 : if (severity != E_STRICT) {
667 9129 : return FAILURE;
668 : }
669 : }
670 :
671 25830848 : return SUCCESS;
672 : }
673 : /* }}} */
674 :
675 : static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int flags TSRMLS_DC) /* {{{ */
676 15343540 : {
677 : char *spec_walk;
678 : int c, i;
679 15343540 : int min_num_args = -1;
680 15343540 : int max_num_args = 0;
681 15343540 : int post_varargs = 0;
682 : zval **arg;
683 : int arg_count;
684 15343540 : int quiet = flags & ZEND_PARSE_PARAMS_QUIET;
685 15343540 : zend_bool have_varargs = 0;
686 15343540 : zval ****varargs = NULL;
687 15343540 : int *n_varargs = NULL;
688 :
689 60441767 : for (spec_walk = type_spec; *spec_walk; spec_walk++) {
690 45098227 : c = *spec_walk;
691 45098227 : switch (c) {
692 : case 'l': case 'd':
693 : case 's': case 'b':
694 : case 'r': case 'a':
695 : case 'o': case 'O':
696 : case 'z': case 'Z':
697 : case 'C': case 'h':
698 : case 'f': case 'A':
699 : case 'H':
700 34367055 : max_num_args++;
701 34367055 : break;
702 :
703 : case '|':
704 7215439 : min_num_args = max_num_args;
705 7215439 : break;
706 :
707 : case '/':
708 : case '!':
709 : /* Pass */
710 3289849 : break;
711 :
712 : case '*':
713 : case '+':
714 225884 : if (have_varargs) {
715 0 : if (!quiet) {
716 0 : zend_function *active_function = EG(current_execute_data)->function_state.function;
717 0 : char *class_name = active_function->common.scope ? active_function->common.scope->name : "";
718 0 : zend_error(E_WARNING, "%s%s%s(): only one varargs specifier (* or +) is permitted",
719 : class_name,
720 : class_name[0] ? "::" : "",
721 : get_active_function_name(TSRMLS_C));
722 : }
723 0 : return FAILURE;
724 : }
725 225884 : have_varargs = 1;
726 : /* we expect at least one parameter in varargs */
727 225884 : if (c == '+') {
728 216013 : max_num_args++;
729 : }
730 : /* mark the beginning of varargs */
731 225884 : post_varargs = max_num_args;
732 225884 : break;
733 :
734 : default:
735 0 : if (!quiet) {
736 0 : zend_function *active_function = EG(current_execute_data)->function_state.function;
737 0 : char *class_name = active_function->common.scope ? active_function->common.scope->name : "";
738 0 : zend_error(E_WARNING, "%s%s%s(): bad type specifier while parsing parameters",
739 : class_name,
740 : class_name[0] ? "::" : "",
741 : get_active_function_name(TSRMLS_C));
742 : }
743 0 : return FAILURE;
744 : }
745 : }
746 :
747 15343540 : if (min_num_args < 0) {
748 8128101 : min_num_args = max_num_args;
749 : }
750 :
751 15343540 : if (have_varargs) {
752 : /* calculate how many required args are at the end of the specifier list */
753 225884 : post_varargs = max_num_args - post_varargs;
754 225884 : max_num_args = -1;
755 : }
756 :
757 15343540 : if (num_args < min_num_args || (num_args > max_num_args && max_num_args > 0)) {
758 4637 : if (!quiet) {
759 2111 : zend_function *active_function = EG(current_execute_data)->function_state.function;
760 2111 : char *class_name = active_function->common.scope ? active_function->common.scope->name : "";
761 2111 : zend_error(E_WARNING, "%s%s%s() expects %s %d parameter%s, %d given",
762 : class_name,
763 : class_name[0] ? "::" : "",
764 : get_active_function_name(TSRMLS_C),
765 : min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
766 : num_args < min_num_args ? min_num_args : max_num_args,
767 : (num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
768 : num_args);
769 : }
770 4637 : return FAILURE;
771 : }
772 :
773 15338903 : arg_count = (int)(zend_uintptr_t) *(zend_vm_stack_top(TSRMLS_C) - 1);
774 :
775 15338903 : if (num_args > arg_count) {
776 2 : zend_error(E_WARNING, "%s(): could not obtain parameters for parsing",
777 : get_active_function_name(TSRMLS_C));
778 2 : return FAILURE;
779 : }
780 :
781 15338901 : i = 0;
782 56724805 : while (num_args-- > 0) {
783 26056132 : if (*type_spec == '|') {
784 1880304 : type_spec++;
785 : }
786 :
787 26056132 : if (*type_spec == '*' || *type_spec == '+') {
788 216155 : int num_varargs = num_args + 1 - post_varargs;
789 :
790 : /* eat up the passed in storage even if it won't be filled in with varargs */
791 216155 : varargs = va_arg(*va, zval ****);
792 216155 : n_varargs = va_arg(*va, int *);
793 216155 : type_spec++;
794 :
795 216155 : if (num_varargs > 0) {
796 216155 : int iv = 0;
797 216155 : zval **p = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count - i));
798 :
799 216155 : *n_varargs = num_varargs;
800 :
801 : /* allocate space for array and store args */
802 216155 : *varargs = safe_emalloc(num_varargs, sizeof(zval **), 0);
803 785962 : while (num_varargs-- > 0) {
804 353652 : (*varargs)[iv++] = p++;
805 : }
806 :
807 : /* adjust how many args we have left and restart loop */
808 216155 : num_args = num_args + 1 - iv;
809 216155 : i += iv;
810 216155 : continue;
811 : } else {
812 0 : *varargs = NULL;
813 0 : *n_varargs = 0;
814 : }
815 : }
816 :
817 25839977 : arg = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count-i));
818 :
819 25839977 : if (zend_parse_arg(i+1, arg, va, &type_spec, quiet TSRMLS_CC) == FAILURE) {
820 : /* clean up varargs array if it was used */
821 9129 : if (varargs && *varargs) {
822 418 : efree(*varargs);
823 418 : *varargs = NULL;
824 : }
825 9129 : return FAILURE;
826 : }
827 25830848 : i++;
828 : }
829 :
830 15329772 : return SUCCESS;
831 : }
832 : /* }}} */
833 :
834 : #define RETURN_IF_ZERO_ARGS(num_args, type_spec, quiet) { \
835 : int __num_args = (num_args); \
836 : \
837 : if (0 == (type_spec)[0] && 0 != __num_args && !(quiet)) { \
838 : char *__space; \
839 : char * __class_name = get_active_class_name(&__space TSRMLS_CC); \
840 : zend_error(E_WARNING, "%s%s%s() expects exactly 0 parameters, %d given", \
841 : __class_name, __space, \
842 : get_active_function_name(TSRMLS_C), __num_args); \
843 : return FAILURE; \
844 : }\
845 : }
846 :
847 : ZEND_API int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...) /* {{{ */
848 643895 : {
849 : va_list va;
850 : int retval;
851 :
852 643895 : RETURN_IF_ZERO_ARGS(num_args, type_spec, flags & ZEND_PARSE_PARAMS_QUIET);
853 :
854 643895 : va_start(va, type_spec);
855 643895 : retval = zend_parse_va_args(num_args, type_spec, &va, flags TSRMLS_CC);
856 643895 : va_end(va);
857 :
858 643895 : return retval;
859 : }
860 : /* }}} */
861 :
862 : ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...) /* {{{ */
863 14591270 : {
864 : va_list va;
865 : int retval;
866 :
867 14591270 : RETURN_IF_ZERO_ARGS(num_args, type_spec, 0);
868 :
869 14590955 : va_start(va, type_spec);
870 14590955 : retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC);
871 14590955 : va_end(va);
872 :
873 14590955 : return retval;
874 : }
875 : /* }}} */
876 :
877 : ZEND_API int zend_parse_method_parameters(int num_args TSRMLS_DC, zval *this_ptr, char *type_spec, ...) /* {{{ */
878 108701 : {
879 : va_list va;
880 : int retval;
881 108701 : char *p = type_spec;
882 : zval **object;
883 : zend_class_entry *ce;
884 :
885 108701 : if (!this_ptr) {
886 103857 : RETURN_IF_ZERO_ARGS(num_args, p, 0);
887 :
888 103857 : va_start(va, type_spec);
889 103857 : retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC);
890 103857 : va_end(va);
891 : } else {
892 4844 : p++;
893 4844 : RETURN_IF_ZERO_ARGS(num_args, p, 0);
894 :
895 4833 : va_start(va, type_spec);
896 :
897 4833 : object = va_arg(va, zval **);
898 4833 : ce = va_arg(va, zend_class_entry *);
899 4833 : *object = this_ptr;
900 :
901 4833 : if (ce && !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) {
902 0 : zend_error(E_CORE_ERROR, "%s::%s() must be derived from %s::%s",
903 : ce->name, get_active_function_name(TSRMLS_C), Z_OBJCE_P(this_ptr)->name, get_active_function_name(TSRMLS_C));
904 : }
905 :
906 4833 : retval = zend_parse_va_args(num_args, p, &va, 0 TSRMLS_CC);
907 4833 : va_end(va);
908 : }
909 108690 : return retval;
910 : }
911 : /* }}} */
912 :
913 : ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args TSRMLS_DC, zval *this_ptr, char *type_spec, ...) /* {{{ */
914 0 : {
915 : va_list va;
916 : int retval;
917 0 : char *p = type_spec;
918 : zval **object;
919 : zend_class_entry *ce;
920 0 : int quiet = flags & ZEND_PARSE_PARAMS_QUIET;
921 :
922 0 : if (!this_ptr) {
923 0 : RETURN_IF_ZERO_ARGS(num_args, p, quiet);
924 :
925 0 : va_start(va, type_spec);
926 0 : retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC);
927 0 : va_end(va);
928 : } else {
929 0 : p++;
930 0 : RETURN_IF_ZERO_ARGS(num_args-1, p, quiet);
931 :
932 0 : va_start(va, type_spec);
933 :
934 0 : object = va_arg(va, zval **);
935 0 : ce = va_arg(va, zend_class_entry *);
936 0 : *object = this_ptr;
937 :
938 0 : if (ce && !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) {
939 0 : if (!quiet) {
940 0 : zend_error(E_CORE_ERROR, "%s::%s() must be derived from %s::%s",
941 : ce->name, get_active_function_name(TSRMLS_C), Z_OBJCE_P(this_ptr)->name, get_active_function_name(TSRMLS_C));
942 : }
943 0 : return FAILURE;
944 : }
945 :
946 0 : retval = zend_parse_va_args(num_args, p, &va, flags TSRMLS_CC);
947 0 : va_end(va);
948 : }
949 0 : return retval;
950 : }
951 : /* }}} */
952 :
953 : /* Argument parsing API -- andrei */
954 : ZEND_API int _array_init(zval *arg, uint size ZEND_FILE_LINE_DC) /* {{{ */
955 2339612 : {
956 2339612 : ALLOC_HASHTABLE_REL(Z_ARRVAL_P(arg));
957 :
958 2339612 : _zend_hash_init(Z_ARRVAL_P(arg), size, NULL, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);
959 2339612 : Z_TYPE_P(arg) = IS_ARRAY;
960 2339612 : return SUCCESS;
961 : }
962 : /* }}} */
963 :
964 : static int zend_merge_property(zval **value TSRMLS_DC, int num_args, va_list args, const zend_hash_key *hash_key) /* {{{ */
965 118 : {
966 : /* which name should a numeric property have ? */
967 118 : if (hash_key->nKeyLength) {
968 118 : zval *obj = va_arg(args, zval *);
969 118 : zend_object_handlers *obj_ht = va_arg(args, zend_object_handlers *);
970 : zval *member;
971 :
972 118 : MAKE_STD_ZVAL(member);
973 118 : ZVAL_STRINGL(member, hash_key->arKey, hash_key->nKeyLength-1, 1);
974 118 : obj_ht->write_property(obj, member, *value TSRMLS_CC);
975 118 : zval_ptr_dtor(&member);
976 : }
977 118 : return ZEND_HASH_APPLY_KEEP;
978 : }
979 : /* }}} */
980 :
981 : /* This function should be called after the constructor has been called
982 : * because it may call __set from the uninitialized object otherwise. */
983 : ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destroy_ht TSRMLS_DC) /* {{{ */
984 59 : {
985 59 : zend_object_handlers *obj_ht = Z_OBJ_HT_P(obj);
986 59 : zend_class_entry *old_scope = EG(scope);
987 :
988 59 : EG(scope) = Z_OBJCE_P(obj);
989 59 : zend_hash_apply_with_arguments(properties TSRMLS_CC, (apply_func_args_t)zend_merge_property, 2, obj, obj_ht);
990 59 : EG(scope) = old_scope;
991 :
992 59 : if (destroy_ht) {
993 59 : zend_hash_destroy(properties);
994 59 : FREE_HASHTABLE(properties);
995 : }
996 59 : }
997 : /* }}} */
998 :
999 : ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
1000 472868 : {
1001 472868 : if (!class_type->constants_updated || !CE_STATIC_MEMBERS(class_type)) {
1002 13760 : zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry);
1003 13760 : zend_class_entry *old_scope = *scope;
1004 :
1005 13760 : *scope = class_type;
1006 13760 : zend_hash_apply_with_argument(&class_type->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
1007 13759 : zend_hash_apply_with_argument(&class_type->default_properties, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
1008 :
1009 13759 : if (!CE_STATIC_MEMBERS(class_type)) {
1010 : HashPosition pos;
1011 : zval **p;
1012 :
1013 10597 : if (class_type->parent) {
1014 2855 : zend_update_class_constants(class_type->parent TSRMLS_CC);
1015 : }
1016 : #if ZTS
1017 : ALLOC_HASHTABLE(CG(static_members)[(zend_intptr_t)(class_type->static_members)]);
1018 : #else
1019 10597 : ALLOC_HASHTABLE(class_type->static_members);
1020 : #endif
1021 10597 : zend_hash_init(CE_STATIC_MEMBERS(class_type), zend_hash_num_elements(&class_type->default_static_members), NULL, ZVAL_PTR_DTOR, 0);
1022 :
1023 10597 : zend_hash_internal_pointer_reset_ex(&class_type->default_static_members, &pos);
1024 21194 : while (zend_hash_get_current_data_ex(&class_type->default_static_members, (void**)&p, &pos) == SUCCESS) {
1025 : char *str_index;
1026 : uint str_length;
1027 : ulong num_index;
1028 : zval **q;
1029 :
1030 0 : zend_hash_get_current_key_ex(&class_type->default_static_members, &str_index, &str_length, &num_index, 0, &pos);
1031 0 : if (Z_ISREF_PP(p) &&
1032 : class_type->parent &&
1033 : zend_hash_find(&class_type->parent->default_static_members, str_index, str_length, (void**)&q) == SUCCESS &&
1034 : *p == *q &&
1035 : zend_hash_find(CE_STATIC_MEMBERS(class_type->parent), str_index, str_length, (void**)&q) == SUCCESS
1036 : ) {
1037 0 : Z_ADDREF_PP(q);
1038 0 : Z_SET_ISREF_PP(q);
1039 0 : zend_hash_add(CE_STATIC_MEMBERS(class_type), str_index, str_length, (void**)q, sizeof(zval*), NULL);
1040 : } else {
1041 : zval *r;
1042 :
1043 0 : ALLOC_ZVAL(r);
1044 0 : *r = **p;
1045 0 : INIT_PZVAL(r);
1046 0 : zval_copy_ctor(r);
1047 0 : zend_hash_add(CE_STATIC_MEMBERS(class_type), str_index, str_length, (void**)&r, sizeof(zval*), NULL);
1048 : }
1049 0 : zend_hash_move_forward_ex(&class_type->default_static_members, &pos);
1050 : }
1051 : }
1052 13759 : zend_hash_apply_with_argument(CE_STATIC_MEMBERS(class_type), (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
1053 :
1054 13759 : *scope = old_scope;
1055 13759 : class_type->constants_updated = 1;
1056 : }
1057 472867 : }
1058 : /* }}} */
1059 :
1060 : /* This function requires 'properties' to contain all props declared in the
1061 : * class and all props being public. If only a subset is given or the class
1062 : * has protected members then you need to merge the properties seperately by
1063 : * calling zend_merge_properties(). */
1064 : ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC) /* {{{ */
1065 467932 : {
1066 : zval *tmp;
1067 : zend_object *object;
1068 :
1069 467932 : if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
1070 1 : char *what = class_type->ce_flags & ZEND_ACC_INTERFACE ? "interface" : "abstract class";
1071 1 : zend_error(E_ERROR, "Cannot instantiate %s %s", what, class_type->name);
1072 : }
1073 :
1074 467931 : zend_update_class_constants(class_type TSRMLS_CC);
1075 :
1076 467930 : Z_TYPE_P(arg) = IS_OBJECT;
1077 467930 : if (class_type->create_object == NULL) {
1078 453012 : Z_OBJVAL_P(arg) = zend_objects_new(&object, class_type TSRMLS_CC);
1079 453012 : if (properties) {
1080 70 : object->properties = properties;
1081 : } else {
1082 452942 : ALLOC_HASHTABLE_REL(object->properties);
1083 452942 : zend_hash_init(object->properties, zend_hash_num_elements(&class_type->default_properties), NULL, ZVAL_PTR_DTOR, 0);
1084 452942 : zend_hash_copy(object->properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
1085 : }
1086 : } else {
1087 14918 : Z_OBJVAL_P(arg) = class_type->create_object(class_type TSRMLS_CC);
1088 : }
1089 467930 : return SUCCESS;
1090 : }
1091 : /* }}} */
1092 :
1093 : ZEND_API int _object_init_ex(zval *arg, zend_class_entry *class_type ZEND_FILE_LINE_DC TSRMLS_DC) /* {{{ */
1094 467763 : {
1095 467763 : return _object_and_properties_init(arg, class_type, 0 ZEND_FILE_LINE_RELAY_CC TSRMLS_CC);
1096 : }
1097 : /* }}} */
1098 :
1099 : ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC TSRMLS_DC) /* {{{ */
1100 1678 : {
1101 1678 : return _object_init_ex(arg, zend_standard_class_def ZEND_FILE_LINE_RELAY_CC TSRMLS_CC);
1102 : }
1103 : /* }}} */
1104 :
1105 : ZEND_API int add_assoc_function(zval *arg, const char *key, void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS)) /* {{{ */
1106 0 : {
1107 0 : zend_error(E_WARNING, "add_assoc_function() is no longer supported");
1108 0 : return FAILURE;
1109 : }
1110 : /* }}} */
1111 :
1112 : ZEND_API int add_assoc_long_ex(zval *arg, const char *key, uint key_len, long n) /* {{{ */
1113 92636 : {
1114 : zval *tmp;
1115 :
1116 92636 : MAKE_STD_ZVAL(tmp);
1117 92636 : ZVAL_LONG(tmp, n);
1118 :
1119 92636 : return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
1120 : }
1121 : /* }}} */
1122 :
1123 : ZEND_API int add_assoc_null_ex(zval *arg, const char *key, uint key_len) /* {{{ */
1124 506 : {
1125 : zval *tmp;
1126 :
1127 506 : MAKE_STD_ZVAL(tmp);
1128 506 : ZVAL_NULL(tmp);
1129 :
1130 506 : return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
1131 : }
1132 : /* }}} */
1133 :
1134 : ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, uint key_len, int b) /* {{{ */
1135 59797 : {
1136 : zval *tmp;
1137 :
1138 59797 : MAKE_STD_ZVAL(tmp);
1139 59797 : ZVAL_BOOL(tmp, b);
1140 :
1141 59797 : return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
1142 : }
1143 : /* }}} */
1144 :
1145 : ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, uint key_len, int r) /* {{{ */
1146 30 : {
1147 : zval *tmp;
1148 :
1149 30 : MAKE_STD_ZVAL(tmp);
1150 30 : ZVAL_RESOURCE(tmp, r);
1151 :
1152 30 : return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
1153 : }
1154 : /* }}} */
1155 :
1156 : ZEND_API int add_assoc_double_ex(zval *arg, const char *key, uint key_len, double d) /* {{{ */
1157 182 : {
1158 : zval *tmp;
1159 :
1160 182 : MAKE_STD_ZVAL(tmp);
1161 182 : ZVAL_DOUBLE(tmp, d);
1162 :
1163 182 : return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
1164 : }
1165 : /* }}} */
1166 :
1167 : ZEND_API int add_assoc_string_ex(zval *arg, const char *key, uint key_len, char *str, int duplicate) /* {{{ */
1168 55192 : {
1169 : zval *tmp;
1170 :
1171 55192 : MAKE_STD_ZVAL(tmp);
1172 55192 : ZVAL_STRING(tmp, str, duplicate);
1173 :
1174 55192 : return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
1175 : }
1176 : /* }}} */
1177 :
1178 : ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, uint key_len, char *str, uint length, int duplicate) /* {{{ */
1179 3779 : {
1180 : zval *tmp;
1181 :
1182 3779 : MAKE_STD_ZVAL(tmp);
1183 3779 : ZVAL_STRINGL(tmp, str, length, duplicate);
1184 :
1185 3779 : return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
1186 : }
1187 : /* }}} */
1188 :
1189 : ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, uint key_len, zval *value) /* {{{ */
1190 219550 : {
1191 219550 : return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &value, sizeof(zval *), NULL);
1192 : }
1193 : /* }}} */
1194 :
1195 : ZEND_API int add_index_long(zval *arg, ulong index, long n) /* {{{ */
1196 12416 : {
1197 : zval *tmp;
1198 :
1199 12416 : MAKE_STD_ZVAL(tmp);
1200 12416 : ZVAL_LONG(tmp, n);
1201 :
1202 12416 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
1203 : }
1204 : /* }}} */
1205 :
1206 : ZEND_API int add_index_null(zval *arg, ulong index) /* {{{ */
1207 11272 : {
1208 : zval *tmp;
1209 :
1210 11272 : MAKE_STD_ZVAL(tmp);
1211 11272 : ZVAL_NULL(tmp);
1212 :
1213 11272 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
1214 : }
1215 : /* }}} */
1216 :
1217 : ZEND_API int add_index_bool(zval *arg, ulong index, int b) /* {{{ */
1218 108 : {
1219 : zval *tmp;
1220 :
1221 108 : MAKE_STD_ZVAL(tmp);
1222 108 : ZVAL_BOOL(tmp, b);
1223 :
1224 108 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
1225 : }
1226 : /* }}} */
1227 :
1228 : ZEND_API int add_index_resource(zval *arg, ulong index, int r) /* {{{ */
1229 34 : {
1230 : zval *tmp;
1231 :
1232 34 : MAKE_STD_ZVAL(tmp);
1233 34 : ZVAL_RESOURCE(tmp, r);
1234 :
1235 34 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
1236 : }
1237 : /* }}} */
1238 :
1239 : ZEND_API int add_index_double(zval *arg, ulong index, double d) /* {{{ */
1240 1007 : {
1241 : zval *tmp;
1242 :
1243 1007 : MAKE_STD_ZVAL(tmp);
1244 1007 : ZVAL_DOUBLE(tmp, d);
1245 :
1246 1007 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
1247 : }
1248 : /* }}} */
1249 :
1250 : ZEND_API int add_index_string(zval *arg, ulong index, const char *str, int duplicate) /* {{{ */
1251 798 : {
1252 : zval *tmp;
1253 :
1254 798 : MAKE_STD_ZVAL(tmp);
1255 798 : ZVAL_STRING(tmp, str, duplicate);
1256 :
1257 798 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
1258 : }
1259 : /* }}} */
1260 :
1261 : ZEND_API int add_index_stringl(zval *arg, ulong index, const char *str, uint length, int duplicate) /* {{{ */
1262 30654 : {
1263 : zval *tmp;
1264 :
1265 30654 : MAKE_STD_ZVAL(tmp);
1266 30654 : ZVAL_STRINGL(tmp, str, length, duplicate);
1267 :
1268 30654 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
1269 : }
1270 : /* }}} */
1271 :
1272 : ZEND_API int add_index_zval(zval *arg, ulong index, zval *value) /* {{{ */
1273 64876 : {
1274 64876 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &value, sizeof(zval *), NULL);
1275 : }
1276 : /* }}} */
1277 :
1278 : ZEND_API int add_next_index_long(zval *arg, long n) /* {{{ */
1279 374519 : {
1280 : zval *tmp;
1281 :
1282 374519 : MAKE_STD_ZVAL(tmp);
1283 374519 : ZVAL_LONG(tmp, n);
1284 :
1285 374519 : return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
1286 : }
1287 : /* }}} */
1288 :
1289 : ZEND_API int add_next_index_null(zval *arg) /* {{{ */
1290 1037 : {
1291 : zval *tmp;
1292 :
1293 1037 : MAKE_STD_ZVAL(tmp);
1294 1037 : ZVAL_NULL(tmp);
1295 :
1296 1037 : return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
1297 : }
1298 : /* }}} */
1299 :
1300 : ZEND_API int add_next_index_bool(zval *arg, int b) /* {{{ */
1301 0 : {
1302 : zval *tmp;
1303 :
1304 0 : MAKE_STD_ZVAL(tmp);
1305 0 : ZVAL_BOOL(tmp, b);
1306 :
1307 0 : return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
1308 : }
1309 : /* }}} */
1310 :
1311 : ZEND_API int add_next_index_resource(zval *arg, int r) /* {{{ */
1312 12 : {
1313 : zval *tmp;
1314 :
1315 12 : MAKE_STD_ZVAL(tmp);
1316 12 : ZVAL_RESOURCE(tmp, r);
1317 :
1318 12 : return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
1319 : }
1320 : /* }}} */
1321 :
1322 : ZEND_API int add_next_index_double(zval *arg, double d) /* {{{ */
1323 241 : {
1324 : zval *tmp;
1325 :
1326 241 : MAKE_STD_ZVAL(tmp);
1327 241 : ZVAL_DOUBLE(tmp, d);
1328 :
1329 241 : return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
1330 : }
1331 : /* }}} */
1332 :
1333 : ZEND_API int add_next_index_string(zval *arg, const char *str, int duplicate) /* {{{ */
1334 7580 : {
1335 : zval *tmp;
1336 :
1337 7580 : MAKE_STD_ZVAL(tmp);
1338 7580 : ZVAL_STRING(tmp, str, duplicate);
1339 :
1340 7580 : return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
1341 : }
1342 : /* }}} */
1343 :
1344 : ZEND_API int add_next_index_stringl(zval *arg, const char *str, uint length, int duplicate) /* {{{ */
1345 1090398 : {
1346 : zval *tmp;
1347 :
1348 1090398 : MAKE_STD_ZVAL(tmp);
1349 1090398 : ZVAL_STRINGL(tmp, str, length, duplicate);
1350 :
1351 1090398 : return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
1352 : }
1353 : /* }}} */
1354 :
1355 : ZEND_API int add_next_index_zval(zval *arg, zval *value) /* {{{ */
1356 27507 : {
1357 27507 : return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &value, sizeof(zval *), NULL);
1358 : }
1359 : /* }}} */
1360 :
1361 : ZEND_API int add_get_assoc_string_ex(zval *arg, const char *key, uint key_len, const char *str, void **dest, int duplicate) /* {{{ */
1362 0 : {
1363 : zval *tmp;
1364 :
1365 0 : MAKE_STD_ZVAL(tmp);
1366 0 : ZVAL_STRING(tmp, str, duplicate);
1367 :
1368 0 : return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), dest);
1369 : }
1370 : /* }}} */
1371 :
1372 : ZEND_API int add_get_assoc_stringl_ex(zval *arg, const char *key, uint key_len, const char *str, uint length, void **dest, int duplicate) /* {{{ */
1373 0 : {
1374 : zval *tmp;
1375 :
1376 0 : MAKE_STD_ZVAL(tmp);
1377 0 : ZVAL_STRINGL(tmp, str, length, duplicate);
1378 :
1379 0 : return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), dest);
1380 : }
1381 : /* }}} */
1382 :
1383 : ZEND_API int add_get_index_long(zval *arg, ulong index, long l, void **dest) /* {{{ */
1384 1317 : {
1385 : zval *tmp;
1386 :
1387 1317 : MAKE_STD_ZVAL(tmp);
1388 1317 : ZVAL_LONG(tmp, l);
1389 :
1390 1317 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
1391 : }
1392 : /* }}} */
1393 :
1394 : ZEND_API int add_get_index_double(zval *arg, ulong index, double d, void **dest) /* {{{ */
1395 0 : {
1396 : zval *tmp;
1397 :
1398 0 : MAKE_STD_ZVAL(tmp);
1399 0 : ZVAL_DOUBLE(tmp, d);
1400 :
1401 0 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
1402 : }
1403 : /* }}} */
1404 :
1405 : ZEND_API int add_get_index_string(zval *arg, ulong index, const char *str, void **dest, int duplicate) /* {{{ */
1406 0 : {
1407 : zval *tmp;
1408 :
1409 0 : MAKE_STD_ZVAL(tmp);
1410 0 : ZVAL_STRING(tmp, str, duplicate);
1411 :
1412 0 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
1413 : }
1414 : /* }}} */
1415 :
1416 : ZEND_API int add_get_index_stringl(zval *arg, ulong index, const char *str, uint length, void **dest, int duplicate) /* {{{ */
1417 43 : {
1418 : zval *tmp;
1419 :
1420 43 : MAKE_STD_ZVAL(tmp);
1421 43 : ZVAL_STRINGL(tmp, str, length, duplicate);
1422 :
1423 43 : return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
1424 : }
1425 : /* }}} */
1426 :
1427 : ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, long n TSRMLS_DC) /* {{{ */
1428 9221 : {
1429 : zval *tmp;
1430 : zval *z_key;
1431 :
1432 9221 : MAKE_STD_ZVAL(tmp);
1433 9221 : ZVAL_LONG(tmp, n);
1434 :
1435 9221 : MAKE_STD_ZVAL(z_key);
1436 9221 : ZVAL_STRINGL(z_key, key, key_len-1, 1);
1437 :
1438 9221 : Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
1439 9221 : zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
1440 9221 : zval_ptr_dtor(&z_key);
1441 9221 : return SUCCESS;
1442 : }
1443 : /* }}} */
1444 :
1445 : ZEND_API int add_property_bool_ex(zval *arg, const char *key, uint key_len, int b TSRMLS_DC) /* {{{ */
1446 345 : {
1447 : zval *tmp;
1448 : zval *z_key;
1449 :
1450 345 : MAKE_STD_ZVAL(tmp);
1451 345 : ZVAL_BOOL(tmp, b);
1452 :
1453 345 : MAKE_STD_ZVAL(z_key);
1454 345 : ZVAL_STRINGL(z_key, key, key_len-1, 1);
1455 :
1456 345 : Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
1457 345 : zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
1458 345 : zval_ptr_dtor(&z_key);
1459 345 : return SUCCESS;
1460 : }
1461 : /* }}} */
1462 :
1463 : ZEND_API int add_property_null_ex(zval *arg, const char *key, uint key_len TSRMLS_DC) /* {{{ */
1464 78 : {
1465 : zval *tmp;
1466 : zval *z_key;
1467 :
1468 78 : MAKE_STD_ZVAL(tmp);
1469 78 : ZVAL_NULL(tmp);
1470 :
1471 78 : MAKE_STD_ZVAL(z_key);
1472 78 : ZVAL_STRINGL(z_key, key, key_len-1, 1);
1473 :
1474 78 : Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
1475 78 : zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
1476 78 : zval_ptr_dtor(&z_key);
1477 78 : return SUCCESS;
1478 : }
1479 : /* }}} */
1480 :
1481 : ZEND_API int add_property_resource_ex(zval *arg, const char *key, uint key_len, long n TSRMLS_DC) /* {{{ */
1482 343338 : {
1483 : zval *tmp;
1484 : zval *z_key;
1485 :
1486 343338 : MAKE_STD_ZVAL(tmp);
1487 343338 : ZVAL_RESOURCE(tmp, n);
1488 :
1489 343338 : MAKE_STD_ZVAL(z_key);
1490 343338 : ZVAL_STRINGL(z_key, key, key_len-1, 1);
1491 :
1492 343338 : Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
1493 343338 : zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
1494 343338 : zval_ptr_dtor(&z_key);
1495 343338 : return SUCCESS;
1496 : }
1497 : /* }}} */
1498 :
1499 : ZEND_API int add_property_double_ex(zval *arg, const char *key, uint key_len, double d TSRMLS_DC) /* {{{ */
1500 0 : {
1501 : zval *tmp;
1502 : zval *z_key;
1503 :
1504 0 : MAKE_STD_ZVAL(tmp);
1505 0 : ZVAL_DOUBLE(tmp, d);
1506 :
1507 0 : MAKE_STD_ZVAL(z_key);
1508 0 : ZVAL_STRINGL(z_key, key, key_len-1, 1);
1509 :
1510 0 : Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
1511 0 : zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
1512 0 : zval_ptr_dtor(&z_key);
1513 0 : return SUCCESS;
1514 : }
1515 : /* }}} */
1516 :
1517 : ZEND_API int add_property_string_ex(zval *arg, const char *key, uint key_len, char *str, int duplicate TSRMLS_DC) /* {{{ */
1518 7846 : {
1519 : zval *tmp;
1520 : zval *z_key;
1521 :
1522 7846 : MAKE_STD_ZVAL(tmp);
1523 7846 : ZVAL_STRING(tmp, str, duplicate);
1524 :
1525 7846 : MAKE_STD_ZVAL(z_key);
1526 7846 : ZVAL_STRINGL(z_key, key, key_len-1, 1);
1527 :
1528 7846 : Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
1529 7846 : zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
1530 7846 : zval_ptr_dtor(&z_key);
1531 7846 : return SUCCESS;
1532 : }
1533 : /* }}} */
1534 :
1535 : ZEND_API int add_property_stringl_ex(zval *arg, const char *key, uint key_len, char *str, uint length, int duplicate TSRMLS_DC) /* {{{ */
1536 728 : {
1537 : zval *tmp;
1538 : zval *z_key;
1539 :
1540 728 : MAKE_STD_ZVAL(tmp);
1541 728 : ZVAL_STRINGL(tmp, str, length, duplicate);
1542 :
1543 728 : MAKE_STD_ZVAL(z_key);
1544 728 : ZVAL_STRINGL(z_key, key, key_len-1, 1);
1545 :
1546 728 : Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
1547 728 : zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
1548 728 : zval_ptr_dtor(&z_key);
1549 728 : return SUCCESS;
1550 : }
1551 : /* }}} */
1552 :
1553 : ZEND_API int add_property_zval_ex(zval *arg, const char *key, uint key_len, zval *value TSRMLS_DC) /* {{{ */
1554 2079 : {
1555 : zval *z_key;
1556 :
1557 2079 : MAKE_STD_ZVAL(z_key);
1558 2079 : ZVAL_STRINGL(z_key, key, key_len-1, 1);
1559 :
1560 2079 : Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, value TSRMLS_CC);
1561 2079 : zval_ptr_dtor(&z_key);
1562 2079 : return SUCCESS;
1563 : }
1564 : /* }}} */
1565 :
1566 : ZEND_API int zend_startup_module_ex(zend_module_entry *module TSRMLS_DC) /* {{{ */
1567 1216995 : {
1568 : int name_len;
1569 : char *lcname;
1570 :
1571 1216995 : if (module->module_started) {
1572 0 : return SUCCESS;
1573 : }
1574 1216995 : module->module_started = 1;
1575 :
1576 : /* Check module dependencies */
1577 1216995 : if (module->deps) {
1578 335027 : const zend_module_dep *dep = module->deps;
1579 :
1580 1216677 : while (dep->name) {
1581 546623 : if (dep->type == MODULE_DEP_REQUIRED) {
1582 : zend_module_entry *req_mod;
1583 :
1584 405559 : name_len = strlen(dep->name);
1585 405559 : lcname = zend_str_tolower_dup(dep->name, name_len);
1586 :
1587 405559 : if (zend_hash_find(&module_registry, lcname, name_len+1, (void**)&req_mod) == FAILURE || !req_mod->module_started) {
1588 0 : efree(lcname);
1589 : /* TODO: Check version relationship */
1590 0 : zend_error(E_CORE_WARNING, "Cannot load module '%s' because required module '%s' is not loaded", module->name, dep->name);
1591 0 : module->module_started = 0;
1592 0 : return FAILURE;
1593 : }
1594 405559 : efree(lcname);
1595 : }
1596 546623 : ++dep;
1597 : }
1598 : }
1599 :
1600 : /* Initialize module globals */
1601 1216995 : if (module->globals_size) {
1602 : #ifdef ZTS
1603 : ts_allocate_id(module->globals_id_ptr, module->globals_size, (ts_allocate_ctor) module->globals_ctor, (ts_allocate_dtor) module->globals_dtor);
1604 : #else
1605 581889 : if (module->globals_ctor) {
1606 528990 : module->globals_ctor(module->globals_ptr TSRMLS_CC);
1607 : }
1608 : #endif
1609 : }
1610 :
1611 1216995 : if (module->module_startup_func) {
1612 1164096 : EG(current_module) = module;
1613 1164096 : if (module->module_startup_func(module->type, module->module_number TSRMLS_CC)==FAILURE) {
1614 0 : zend_error(E_CORE_ERROR,"Unable to start %s module", module->name);
1615 0 : EG(current_module) = NULL;
1616 0 : return FAILURE;
1617 : }
1618 1164096 : EG(current_module) = NULL;
1619 : }
1620 1216995 : return SUCCESS;
1621 : }
1622 : /* }}} */
1623 :
1624 : static void zend_sort_modules(void *base, size_t count, size_t siz, compare_func_t compare TSRMLS_DC) /* {{{ */
1625 17633 : {
1626 17633 : Bucket **b1 = base;
1627 : Bucket **b2;
1628 17633 : Bucket **end = b1 + count;
1629 : Bucket *tmp;
1630 : zend_module_entry *m, *r;
1631 :
1632 1234628 : while (b1 < end) {
1633 1287527 : try_again:
1634 1287527 : m = (zend_module_entry*)(*b1)->pData;
1635 1287527 : if (!m->module_started && m->deps) {
1636 423192 : const zend_module_dep *dep = m->deps;
1637 1393007 : while (dep->name) {
1638 634788 : if (dep->type == MODULE_DEP_REQUIRED || dep->type == MODULE_DEP_OPTIONAL) {
1639 617155 : b2 = b1 + 1;
1640 15579479 : while (b2 < end) {
1641 14433334 : r = (zend_module_entry*)(*b2)->pData;
1642 14433334 : if (strcasecmp(dep->name, r->name) == 0) {
1643 88165 : tmp = *b1;
1644 88165 : *b1 = *b2;
1645 88165 : *b2 = tmp;
1646 88165 : goto try_again;
1647 : }
1648 14345169 : b2++;
1649 : }
1650 : }
1651 546623 : dep++;
1652 : }
1653 : }
1654 1199362 : b1++;
1655 : }
1656 17633 : }
1657 : /* }}} */
1658 :
1659 : ZEND_API int zend_startup_modules(TSRMLS_D) /* {{{ */
1660 17633 : {
1661 17633 : zend_hash_sort(&module_registry, zend_sort_modules, NULL, 0 TSRMLS_CC);
1662 17633 : zend_hash_apply(&module_registry, (apply_func_t)zend_startup_module_ex TSRMLS_CC);
1663 17633 : return SUCCESS;
1664 : }
1665 : /* }}} */
1666 :
1667 : ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TSRMLS_DC) /* {{{ */
1668 1216995 : {
1669 : int name_len;
1670 : char *lcname;
1671 : zend_module_entry *module_ptr;
1672 :
1673 1216995 : if (!module) {
1674 0 : return NULL;
1675 : }
1676 :
1677 : #if 0
1678 : zend_printf("%s: Registering module %d\n", module->name, module->module_number);
1679 : #endif
1680 :
1681 : /* Check module dependencies */
1682 1216995 : if (module->deps) {
1683 335027 : const zend_module_dep *dep = module->deps;
1684 :
1685 1216677 : while (dep->name) {
1686 546623 : if (dep->type == MODULE_DEP_CONFLICTS) {
1687 17633 : name_len = strlen(dep->name);
1688 17633 : lcname = zend_str_tolower_dup(dep->name, name_len);
1689 :
1690 17633 : if (zend_hash_exists(&module_registry, lcname, name_len+1)) {
1691 0 : efree(lcname);
1692 : /* TODO: Check version relationship */
1693 0 : zend_error(E_CORE_WARNING, "Cannot load module '%s' because conflicting module '%s' is already loaded", module->name, dep->name);
1694 0 : return NULL;
1695 : }
1696 17633 : efree(lcname);
1697 : }
1698 546623 : ++dep;
1699 : }
1700 : }
1701 :
1702 1216995 : name_len = strlen(module->name);
1703 1216995 : lcname = zend_str_tolower_dup(module->name, name_len);
1704 :
1705 1216995 : if (zend_hash_add(&module_registry, lcname, name_len+1, (void *)module, sizeof(zend_module_entry), (void**)&module_ptr)==FAILURE) {
1706 0 : zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name);
1707 0 : efree(lcname);
1708 0 : return NULL;
1709 : }
1710 1216995 : efree(lcname);
1711 1216995 : module = module_ptr;
1712 1216995 : EG(current_module) = module;
1713 :
1714 1216995 : if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type TSRMLS_CC)==FAILURE) {
1715 0 : EG(current_module) = NULL;
1716 0 : zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name);
1717 0 : return NULL;
1718 : }
1719 :
1720 1216995 : EG(current_module) = NULL;
1721 1216995 : return module;
1722 : }
1723 : /* }}} */
1724 :
1725 : ZEND_API zend_module_entry* zend_register_internal_module(zend_module_entry *module TSRMLS_DC) /* {{{ */
1726 1199362 : {
1727 1199362 : module->module_number = zend_next_free_module();
1728 1199362 : module->type = MODULE_PERSISTENT;
1729 1199362 : return zend_register_module_ex(module TSRMLS_CC);
1730 : }
1731 : /* }}} */
1732 :
1733 : ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, int error_type TSRMLS_DC) /* {{{ */
1734 1760552 : {
1735 : char lcname[16];
1736 : int name_len;
1737 :
1738 : /* we don't care if the function name is longer, in fact lowercasing only
1739 : * the beginning of the name speeds up the check process */
1740 1760552 : name_len = strlen(fptr->common.function_name);
1741 1760552 : zend_str_tolower_copy(lcname, fptr->common.function_name, MIN(name_len, sizeof(lcname)-1));
1742 1760552 : lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */
1743 :
1744 1760552 : if (name_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME)) && fptr->common.num_args != 0) {
1745 1 : zend_error(error_type, "Destructor %s::%s() cannot take arguments", ce->name, ZEND_DESTRUCTOR_FUNC_NAME);
1746 1760551 : } else if (name_len == sizeof(ZEND_CLONE_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)) && fptr->common.num_args != 0) {
1747 1 : zend_error(error_type, "Method %s::%s() cannot accept any arguments", ce->name, ZEND_CLONE_FUNC_NAME);
1748 1760602 : } else if (name_len == sizeof(ZEND_GET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME))) {
1749 54 : if (fptr->common.num_args != 1) {
1750 1 : zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_GET_FUNC_NAME);
1751 53 : } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
1752 1 : zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_GET_FUNC_NAME);
1753 : }
1754 1760547 : } else if (name_len == sizeof(ZEND_SET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME))) {
1755 55 : if (fptr->common.num_args != 2) {
1756 2 : zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_SET_FUNC_NAME);
1757 53 : } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
1758 2 : zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_SET_FUNC_NAME);
1759 : }
1760 1760455 : } else if (name_len == sizeof(ZEND_UNSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME))) {
1761 16 : if (fptr->common.num_args != 1) {
1762 1 : zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_UNSET_FUNC_NAME);
1763 15 : } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
1764 1 : zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_UNSET_FUNC_NAME);
1765 : }
1766 1760436 : } else if (name_len == sizeof(ZEND_ISSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME))) {
1767 13 : if (fptr->common.num_args != 1) {
1768 1 : zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_ISSET_FUNC_NAME);
1769 12 : } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
1770 1 : zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_ISSET_FUNC_NAME);
1771 : }
1772 1778095 : } else if (name_len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME))) {
1773 17686 : if (fptr->common.num_args != 2) {
1774 1 : zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_CALL_FUNC_NAME);
1775 17685 : } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
1776 2 : zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_CALL_FUNC_NAME);
1777 : }
1778 1742744 : } else if (name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME) - 1 &&
1779 : !memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1)
1780 : ) {
1781 18 : if (fptr->common.num_args != 2) {
1782 0 : zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_CALLSTATIC_FUNC_NAME);
1783 18 : } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
1784 0 : zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_CALLSTATIC_FUNC_NAME);
1785 : }
1786 1742708 : } else if (name_len == sizeof(ZEND_TOSTRING_FUNC_NAME) - 1 &&
1787 : !memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && fptr->common.num_args != 0
1788 : ) {
1789 1 : zend_error(error_type, "Method %s::%s() cannot take arguments", ce->name, ZEND_TOSTRING_FUNC_NAME);
1790 : }
1791 1760536 : }
1792 : /* }}} */
1793 :
1794 : /* registers all functions in *library_functions in the function hash */
1795 : ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_function_entry *functions, HashTable *function_table, int type TSRMLS_DC) /* {{{ */
1796 3596972 : {
1797 3596972 : const zend_function_entry *ptr = functions;
1798 : zend_function function, *reg_function;
1799 3596972 : zend_internal_function *internal_function = (zend_internal_function *)&function;
1800 3596972 : int count=0, unload=0;
1801 3596972 : HashTable *target_function_table = function_table;
1802 : int error_type;
1803 3596972 : zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL;
1804 : char *lowercase_name;
1805 : int fname_len;
1806 3596972 : char *lc_class_name = NULL;
1807 3596972 : int class_name_len = 0;
1808 :
1809 3596972 : if (type==MODULE_PERSISTENT) {
1810 3596972 : error_type = E_CORE_WARNING;
1811 : } else {
1812 0 : error_type = E_WARNING;
1813 : }
1814 :
1815 3596972 : if (!target_function_table) {
1816 1181247 : target_function_table = CG(function_table);
1817 : }
1818 3596972 : internal_function->type = ZEND_INTERNAL_FUNCTION;
1819 3596972 : internal_function->module = EG(current_module);
1820 :
1821 3596972 : if (scope) {
1822 2415722 : class_name_len = strlen(scope->name);
1823 2415722 : if ((lc_class_name = zend_memrchr(scope->name, '\\', class_name_len))) {
1824 0 : ++lc_class_name;
1825 0 : class_name_len -= (lc_class_name - scope->name);
1826 0 : lc_class_name = zend_str_tolower_dup(lc_class_name, class_name_len);
1827 : } else {
1828 2415722 : lc_class_name = zend_str_tolower_dup(scope->name, class_name_len);
1829 : }
1830 : }
1831 :
1832 66458296 : while (ptr->fname) {
1833 59264352 : internal_function->handler = ptr->handler;
1834 59264352 : internal_function->function_name = (char*)ptr->fname;
1835 59264352 : internal_function->scope = scope;
1836 59264352 : internal_function->prototype = NULL;
1837 59264352 : if (ptr->arg_info) {
1838 51699792 : internal_function->arg_info = (zend_arg_info*)ptr->arg_info+1;
1839 51699792 : internal_function->num_args = ptr->num_args;
1840 : /* Currently you cannot denote that the function can accept less arguments than num_args */
1841 51699792 : if (ptr->arg_info[0].required_num_args == -1) {
1842 20648079 : internal_function->required_num_args = ptr->num_args;
1843 : } else {
1844 31051713 : internal_function->required_num_args = ptr->arg_info[0].required_num_args;
1845 : }
1846 51699792 : internal_function->pass_rest_by_reference = ptr->arg_info[0].pass_by_reference;
1847 51699792 : internal_function->return_reference = ptr->arg_info[0].return_reference;
1848 : } else {
1849 7564560 : internal_function->arg_info = NULL;
1850 7564560 : internal_function->num_args = 0;
1851 7564560 : internal_function->required_num_args = 0;
1852 7564560 : internal_function->pass_rest_by_reference = 0;
1853 7564560 : internal_function->return_reference = 0;
1854 : }
1855 59264352 : if (ptr->flags) {
1856 12854457 : if (!(ptr->flags & ZEND_ACC_PPP_MASK)) {
1857 335027 : if (ptr->flags != ZEND_ACC_DEPRECATED || scope) {
1858 0 : zend_error(error_type, "Invalid access level for %s%s%s() - access must be exactly one of public, protected or private", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
1859 : }
1860 335027 : internal_function->fn_flags = ZEND_ACC_PUBLIC | ptr->flags;
1861 : } else {
1862 12519430 : internal_function->fn_flags = ptr->flags;
1863 : }
1864 : } else {
1865 46409895 : internal_function->fn_flags = ZEND_ACC_PUBLIC;
1866 : }
1867 59264352 : if (ptr->flags & ZEND_ACC_ABSTRACT) {
1868 458458 : if (scope) {
1869 : /* This is a class that must be abstract itself. Here we set the check info. */
1870 458458 : scope->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
1871 458458 : if (!(scope->ce_flags & ZEND_ACC_INTERFACE)) {
1872 : /* Since the class is not an interface it needs to be declared as a abstract class. */
1873 : /* Since here we are handling internal functions only we can add the keyword flag. */
1874 : /* This time we set the flag for the keyword 'abstract'. */
1875 52899 : scope->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
1876 : }
1877 : }
1878 458458 : if (ptr->flags & ZEND_ACC_STATIC && (!scope || !(scope->ce_flags & ZEND_ACC_INTERFACE))) {
1879 0 : zend_error(error_type, "Static function %s%s%s() cannot be abstract", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
1880 : }
1881 : } else {
1882 58805894 : if (scope && (scope->ce_flags & ZEND_ACC_INTERFACE)) {
1883 0 : efree(lc_class_name);
1884 0 : zend_error(error_type, "Interface %s cannot contain non abstract method %s()", scope->name, ptr->fname);
1885 0 : return FAILURE;
1886 : }
1887 58805894 : if (!internal_function->handler) {
1888 0 : if (scope) {
1889 0 : efree(lc_class_name);
1890 : }
1891 0 : zend_error(error_type, "Method %s%s%s() cannot be a NULL function", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
1892 0 : zend_unregister_functions(functions, count, target_function_table TSRMLS_CC);
1893 0 : return FAILURE;
1894 : }
1895 : }
1896 59264352 : fname_len = strlen(ptr->fname);
1897 59264352 : lowercase_name = zend_str_tolower_dup(ptr->fname, fname_len);
1898 59264352 : if (zend_hash_add(target_function_table, lowercase_name, fname_len+1, &function, sizeof(zend_function), (void**)®_function) == FAILURE) {
1899 0 : unload=1;
1900 0 : efree(lowercase_name);
1901 0 : break;
1902 : }
1903 59264352 : if (scope) {
1904 : /* Look for ctor, dtor, clone
1905 : * If it's an old-style constructor, store it only if we don't have
1906 : * a constructor already.
1907 : */
1908 22834735 : if ((fname_len == class_name_len) && !memcmp(lowercase_name, lc_class_name, class_name_len+1) && !ctor) {
1909 141064 : ctor = reg_function;
1910 23716385 : } else if ((fname_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) {
1911 1163778 : ctor = reg_function;
1912 21441728 : } else if ((fname_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME))) {
1913 52899 : dtor = reg_function;
1914 52899 : if (internal_function->num_args) {
1915 0 : zend_error(error_type, "Destructor %s::%s() cannot take arguments", scope->name, ptr->fname);
1916 : }
1917 21441728 : } else if ((fname_len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME))) {
1918 105798 : clone = reg_function;
1919 21247765 : } else if ((fname_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME))) {
1920 17633 : __call = reg_function;
1921 21212499 : } else if ((fname_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME))) {
1922 0 : __callstatic = reg_function;
1923 21476994 : } else if ((fname_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME))) {
1924 264495 : __tostring = reg_function;
1925 20948004 : } else if ((fname_len == sizeof(ZEND_GET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME))) {
1926 0 : __get = reg_function;
1927 20948004 : } else if ((fname_len == sizeof(ZEND_SET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME))) {
1928 0 : __set = reg_function;
1929 20948004 : } else if ((fname_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME))) {
1930 0 : __unset = reg_function;
1931 20948004 : } else if ((fname_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME))) {
1932 0 : __isset = reg_function;
1933 : } else {
1934 20948004 : reg_function = NULL;
1935 : }
1936 22693671 : if (reg_function) {
1937 1745667 : zend_check_magic_method_implementation(scope, reg_function, error_type TSRMLS_CC);
1938 : }
1939 : }
1940 59264352 : ptr++;
1941 59264352 : count++;
1942 59264352 : efree(lowercase_name);
1943 : }
1944 3596972 : if (unload) { /* before unloading, display all remaining bad function in the module */
1945 0 : if (scope) {
1946 0 : efree(lc_class_name);
1947 : }
1948 0 : while (ptr->fname) {
1949 0 : fname_len = strlen(ptr->fname);
1950 0 : lowercase_name = zend_str_tolower_dup(ptr->fname, fname_len);
1951 0 : if (zend_hash_exists(target_function_table, lowercase_name, fname_len+1)) {
1952 0 : zend_error(error_type, "Function registration failed - duplicate name - %s%s%s", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
1953 : }
1954 0 : efree(lowercase_name);
1955 0 : ptr++;
1956 : }
1957 0 : zend_unregister_functions(functions, count, target_function_table TSRMLS_CC);
1958 0 : return FAILURE;
1959 : }
1960 3596972 : if (scope) {
1961 2415722 : scope->constructor = ctor;
1962 2415722 : scope->destructor = dtor;
1963 2415722 : scope->clone = clone;
1964 2415722 : scope->__call = __call;
1965 2415722 : scope->__callstatic = __callstatic;
1966 2415722 : scope->__tostring = __tostring;
1967 2415722 : scope->__get = __get;
1968 2415722 : scope->__set = __set;
1969 2415722 : scope->__unset = __unset;
1970 2415722 : scope->__isset = __isset;
1971 2415722 : if (ctor) {
1972 1304842 : ctor->common.fn_flags |= ZEND_ACC_CTOR;
1973 1304842 : if (ctor->common.fn_flags & ZEND_ACC_STATIC) {
1974 0 : zend_error(error_type, "Constructor %s::%s() cannot be static", scope->name, ctor->common.function_name);
1975 : }
1976 1304842 : ctor->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
1977 : }
1978 2415722 : if (dtor) {
1979 52899 : dtor->common.fn_flags |= ZEND_ACC_DTOR;
1980 52899 : if (dtor->common.fn_flags & ZEND_ACC_STATIC) {
1981 0 : zend_error(error_type, "Destructor %s::%s() cannot be static", scope->name, dtor->common.function_name);
1982 : }
1983 52899 : dtor->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
1984 : }
1985 2415722 : if (clone) {
1986 105798 : clone->common.fn_flags |= ZEND_ACC_CLONE;
1987 105798 : if (clone->common.fn_flags & ZEND_ACC_STATIC) {
1988 0 : zend_error(error_type, "Constructor %s::%s() cannot be static", scope->name, clone->common.function_name);
1989 : }
1990 105798 : clone->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
1991 : }
1992 2415722 : if (__call) {
1993 17633 : if (__call->common.fn_flags & ZEND_ACC_STATIC) {
1994 0 : zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __call->common.function_name);
1995 : }
1996 17633 : __call->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
1997 : }
1998 2415722 : if (__callstatic) {
1999 0 : if (!(__callstatic->common.fn_flags & ZEND_ACC_STATIC)) {
2000 0 : zend_error(error_type, "Method %s::%s() must be static", scope->name, __callstatic->common.function_name);
2001 : }
2002 0 : __callstatic->common.fn_flags |= ZEND_ACC_STATIC;
2003 : }
2004 2415722 : if (__tostring) {
2005 264495 : if (__tostring->common.fn_flags & ZEND_ACC_STATIC) {
2006 0 : zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __tostring->common.function_name);
2007 : }
2008 264495 : __tostring->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2009 : }
2010 2415722 : if (__get) {
2011 0 : if (__get->common.fn_flags & ZEND_ACC_STATIC) {
2012 0 : zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __get->common.function_name);
2013 : }
2014 0 : __get->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2015 : }
2016 2415722 : if (__set) {
2017 0 : if (__set->common.fn_flags & ZEND_ACC_STATIC) {
2018 0 : zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __set->common.function_name);
2019 : }
2020 0 : __set->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2021 : }
2022 2415722 : if (__unset) {
2023 0 : if (__unset->common.fn_flags & ZEND_ACC_STATIC) {
2024 0 : zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __unset->common.function_name);
2025 : }
2026 0 : __unset->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2027 : }
2028 2415722 : if (__isset) {
2029 0 : if (__isset->common.fn_flags & ZEND_ACC_STATIC) {
2030 0 : zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __isset->common.function_name);
2031 : }
2032 0 : __isset->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
2033 : }
2034 2415722 : efree(lc_class_name);
2035 : }
2036 3596972 : return SUCCESS;
2037 : }
2038 : /* }}} */
2039 :
2040 : /* count=-1 means erase all functions, otherwise,
2041 : * erase the first count functions
2042 : */
2043 : ZEND_API void zend_unregister_functions(const zend_function_entry *functions, int count, HashTable *function_table TSRMLS_DC) /* {{{ */
2044 1165890 : {
2045 1165890 : const zend_function_entry *ptr = functions;
2046 1165890 : int i=0;
2047 1165890 : HashTable *target_function_table = function_table;
2048 :
2049 1165890 : if (!target_function_table) {
2050 1165890 : target_function_table = CG(function_table);
2051 : }
2052 38951325 : while (ptr->fname) {
2053 36619545 : if (count!=-1 && i>=count) {
2054 0 : break;
2055 : }
2056 : #if 0
2057 : zend_printf("Unregistering %s()\n", ptr->fname);
2058 : #endif
2059 36619545 : zend_hash_del(target_function_table, ptr->fname, strlen(ptr->fname)+1);
2060 36619545 : ptr++;
2061 36619545 : i++;
2062 : }
2063 1165890 : }
2064 : /* }}} */
2065 :
2066 : ZEND_API int zend_startup_module(zend_module_entry *module) /* {{{ */
2067 0 : {
2068 : TSRMLS_FETCH();
2069 :
2070 0 : if ((module = zend_register_internal_module(module TSRMLS_CC)) != NULL && zend_startup_module_ex(module TSRMLS_CC) == SUCCESS) {
2071 0 : return SUCCESS;
2072 : }
2073 0 : return FAILURE;
2074 : }
2075 : /* }}} */
2076 :
2077 : ZEND_API int zend_get_module_started(const char *module_name) /* {{{ */
2078 0 : {
2079 : zend_module_entry *module;
2080 :
2081 0 : return (zend_hash_find(&module_registry, module_name, strlen(module_name)+1, (void**)&module) == SUCCESS && module->module_started) ? SUCCESS : FAILURE;
2082 : }
2083 : /* }}} */
2084 :
2085 : void module_destructor(zend_module_entry *module) /* {{{ */
2086 1219200 : {
2087 : TSRMLS_FETCH();
2088 :
2089 1219200 : if (module->type == MODULE_TEMPORARY) {
2090 0 : zend_clean_module_rsrc_dtors(module->module_number TSRMLS_CC);
2091 0 : clean_module_constants(module->module_number TSRMLS_CC);
2092 : }
2093 :
2094 1219200 : if (module->module_started && module->module_shutdown_func) {
2095 : #if 0
2096 : zend_printf("%s: Module shutdown\n", module->name);
2097 : #endif
2098 795240 : module->module_shutdown_func(module->type, module->module_number TSRMLS_CC);
2099 : }
2100 :
2101 : /* Deinitilaise module globals */
2102 1219200 : if (module->globals_size) {
2103 : #ifdef ZTS
2104 : ts_free_id(*module->globals_id_ptr);
2105 : #else
2106 582945 : if (module->globals_dtor) {
2107 88325 : module->globals_dtor(module->globals_ptr TSRMLS_CC);
2108 : }
2109 : #endif
2110 : }
2111 :
2112 1219200 : module->module_started=0;
2113 1219200 : if (module->functions) {
2114 1165890 : zend_unregister_functions(module->functions, -1, NULL TSRMLS_CC);
2115 : }
2116 :
2117 : #if HAVE_LIBDL
2118 : #if !(defined(NETWARE) && defined(APACHE_1_BUILD))
2119 1219200 : if (module->handle) {
2120 0 : DL_UNLOAD(module->handle);
2121 : }
2122 : #endif
2123 : #endif
2124 1219200 : }
2125 : /* }}} */
2126 :
2127 : /* call request startup for all modules */
2128 : int module_registry_request_startup(zend_module_entry *module TSRMLS_DC) /* {{{ */
2129 1216029 : {
2130 1216029 : if (module->request_startup_func) {
2131 : #if 0
2132 : zend_printf("%s: Request startup\n", module->name);
2133 : #endif
2134 352380 : if (module->request_startup_func(module->type, module->module_number TSRMLS_CC)==FAILURE) {
2135 0 : zend_error(E_WARNING, "request_startup() for %s module failed", module->name);
2136 0 : exit(1);
2137 : }
2138 : }
2139 1216029 : return 0;
2140 : }
2141 : /* }}} */
2142 :
2143 : /* call request shutdown for all modules */
2144 : int module_registry_cleanup(zend_module_entry *module TSRMLS_DC) /* {{{ */
2145 1218234 : {
2146 1218234 : if (module->request_shutdown_func) {
2147 : #if 0
2148 : zend_printf("%s: Request shutdown\n", module->name);
2149 : #endif
2150 423624 : module->request_shutdown_func(module->type, module->module_number TSRMLS_CC);
2151 : }
2152 1218234 : return 0;
2153 : }
2154 : /* }}} */
2155 :
2156 : int module_registry_unload_temp(const zend_module_entry *module TSRMLS_DC) /* {{{ */
2157 17651 : {
2158 17651 : return (module->type == MODULE_TEMPORARY) ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_STOP;
2159 : }
2160 : /* }}} */
2161 :
2162 : /* return the next free module number */
2163 : int zend_next_free_module(void) /* {{{ */
2164 1199362 : {
2165 1199362 : return ++module_count;
2166 : }
2167 : /* }}} */
2168 :
2169 : static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class_entry, zend_uint ce_flags TSRMLS_DC) /* {{{ */
2170 2768382 : {
2171 2768382 : zend_class_entry *class_entry = malloc(sizeof(zend_class_entry));
2172 2768382 : char *lowercase_name = malloc(orig_class_entry->name_length + 1);
2173 2768382 : *class_entry = *orig_class_entry;
2174 :
2175 2768382 : class_entry->type = ZEND_INTERNAL_CLASS;
2176 2768382 : zend_initialize_class_data(class_entry, 0 TSRMLS_CC);
2177 2768382 : class_entry->ce_flags = ce_flags;
2178 2768382 : class_entry->module = EG(current_module);
2179 :
2180 2768382 : if (class_entry->builtin_functions) {
2181 2415722 : zend_register_functions(class_entry, class_entry->builtin_functions, &class_entry->function_table, MODULE_PERSISTENT TSRMLS_CC);
2182 : }
2183 :
2184 2768382 : zend_str_tolower_copy(lowercase_name, orig_class_entry->name, class_entry->name_length);
2185 2768382 : zend_hash_update(CG(class_table), lowercase_name, class_entry->name_length+1, &class_entry, sizeof(zend_class_entry *), NULL);
2186 2768382 : free(lowercase_name);
2187 2768382 : return class_entry;
2188 : }
2189 : /* }}} */
2190 :
2191 : /* If parent_ce is not NULL then it inherits from parent_ce
2192 : * If parent_ce is NULL and parent_name isn't then it looks for the parent and inherits from it
2193 : * If both parent_ce and parent_name are NULL it does a regular class registration
2194 : * If parent_name is specified but not found NULL is returned
2195 : */
2196 : ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce, char *parent_name TSRMLS_DC) /* {{{ */
2197 1604603 : {
2198 : zend_class_entry *register_class;
2199 :
2200 1604603 : if (!parent_ce && parent_name) {
2201 : zend_class_entry **pce;
2202 0 : if (zend_hash_find(CG(class_table), parent_name, strlen(parent_name)+1, (void **) &pce)==FAILURE) {
2203 0 : return NULL;
2204 : } else {
2205 0 : parent_ce = *pce;
2206 : }
2207 : }
2208 :
2209 1604603 : register_class = zend_register_internal_class(class_entry TSRMLS_CC);
2210 :
2211 1604603 : if (parent_ce) {
2212 1110879 : zend_do_inheritance(register_class, parent_ce TSRMLS_CC);
2213 : }
2214 1604603 : return register_class;
2215 : }
2216 : /* }}} */
2217 :
2218 : ZEND_API void zend_class_implements(zend_class_entry *class_entry TSRMLS_DC, int num_interfaces, ...) /* {{{ */
2219 952182 : {
2220 : zend_class_entry *interface_entry;
2221 : va_list interface_list;
2222 952182 : va_start(interface_list, num_interfaces);
2223 :
2224 2909445 : while (num_interfaces--) {
2225 1005081 : interface_entry = va_arg(interface_list, zend_class_entry *);
2226 1005081 : zend_do_implement_interface(class_entry, interface_entry TSRMLS_CC);
2227 : }
2228 :
2229 952182 : va_end(interface_list);
2230 952182 : }
2231 : /* }}} */
2232 :
2233 : /* A class that contains at least one abstract method automatically becomes an abstract class.
2234 : */
2235 : ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *orig_class_entry TSRMLS_DC) /* {{{ */
2236 2556786 : {
2237 2556786 : return do_register_internal_class(orig_class_entry, 0 TSRMLS_CC);
2238 : }
2239 : /* }}} */
2240 :
2241 : ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry TSRMLS_DC) /* {{{ */
2242 211596 : {
2243 211596 : return do_register_internal_class(orig_class_entry, ZEND_ACC_INTERFACE TSRMLS_CC);
2244 : }
2245 : /* }}} */
2246 :
2247 : ZEND_API int zend_register_class_alias_ex(const char *name, int name_len, zend_class_entry *ce TSRMLS_DC) /* {{{ */
2248 24 : {
2249 24 : char *lcname = zend_str_tolower_dup(name, name_len);
2250 : int ret;
2251 :
2252 24 : ret = zend_hash_add(CG(class_table), lcname, name_len+1, &ce, sizeof(zend_class_entry *), NULL);
2253 24 : efree(lcname);
2254 24 : if (ret == SUCCESS) {
2255 20 : ce->refcount++;
2256 : }
2257 24 : return ret;
2258 : }
2259 : /* }}} */
2260 :
2261 : ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_length, zend_bool is_ref, int num_symbol_tables, ...) /* {{{ */
2262 144 : {
2263 : HashTable *symbol_table;
2264 : va_list symbol_table_list;
2265 :
2266 144 : if (num_symbol_tables <= 0) return FAILURE;
2267 :
2268 144 : Z_SET_ISREF_TO_P(symbol, is_ref);
2269 :
2270 144 : va_start(symbol_table_list, num_symbol_tables);
2271 447 : while (num_symbol_tables-- > 0) {
2272 159 : symbol_table = va_arg(symbol_table_list, HashTable *);
2273 159 : zend_hash_update(symbol_table, name, name_length + 1, &symbol, sizeof(zval *), NULL);
2274 159 : zval_add_ref(&symbol);
2275 : }
2276 144 : va_end(symbol_table_list);
2277 144 : return SUCCESS;
2278 : }
2279 : /* }}} */
2280 :
2281 : /* Disabled functions support */
2282 :
2283 : /* {{{ proto void display_disabled_function(void)
2284 : Dummy function which displays an error when a disabled function is called. */
2285 : ZEND_API ZEND_FUNCTION(display_disabled_function)
2286 1 : {
2287 1 : zend_error(E_WARNING, "%s() has been disabled for security reasons", get_active_function_name(TSRMLS_C));
2288 1 : }
2289 : /* }}} */
2290 :
2291 : static zend_function_entry disabled_function[] = {
2292 : ZEND_FE(display_disabled_function, NULL)
2293 : { NULL, NULL, NULL }
2294 : };
2295 :
2296 : ZEND_API int zend_disable_function(char *function_name, uint function_name_length TSRMLS_DC) /* {{{ */
2297 3 : {
2298 3 : if (zend_hash_del(CG(function_table), function_name, function_name_length+1)==FAILURE) {
2299 0 : return FAILURE;
2300 : }
2301 3 : disabled_function[0].fname = function_name;
2302 3 : return zend_register_functions(NULL, disabled_function, CG(function_table), MODULE_PERSISTENT TSRMLS_CC);
2303 : }
2304 : /* }}} */
2305 :
2306 : static zend_object_value display_disabled_class(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
2307 1 : {
2308 : zend_object_value retval;
2309 : zend_object *intern;
2310 1 : retval = zend_objects_new(&intern, class_type TSRMLS_CC);
2311 1 : ALLOC_HASHTABLE(intern->properties);
2312 1 : zend_hash_init(intern->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
2313 1 : zend_error(E_WARNING, "%s() has been disabled for security reasons", class_type->name);
2314 1 : return retval;
2315 : }
2316 : /* }}} */
2317 :
2318 : static const zend_function_entry disabled_class_new[] = {
2319 : { NULL, NULL, NULL }
2320 : };
2321 :
2322 : ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC) /* {{{ */
2323 1 : {
2324 : zend_class_entry disabled_class;
2325 :
2326 1 : zend_str_tolower(class_name, class_name_length);
2327 1 : if (zend_hash_del(CG(class_table), class_name, class_name_length+1)==FAILURE) {
2328 0 : return FAILURE;
2329 : }
2330 1 : INIT_OVERLOADED_CLASS_ENTRY_EX(disabled_class, class_name, class_name_length, disabled_class_new, NULL, NULL, NULL, NULL, NULL);
2331 1 : disabled_class.create_object = display_disabled_class;
2332 1 : disabled_class.name_length = class_name_length;
2333 1 : zend_register_internal_class(&disabled_class TSRMLS_CC);
2334 1 : return SUCCESS;
2335 : }
2336 : /* }}} */
2337 :
2338 : static int zend_is_callable_check_class(const char *name, int name_len, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
2339 302 : {
2340 302 : int ret = 0;
2341 : zend_class_entry **pce;
2342 302 : char *lcname = zend_str_tolower_dup(name, name_len);
2343 :
2344 318 : if (name_len == sizeof("self") - 1 &&
2345 : !memcmp(lcname, "self", sizeof("self") - 1)) {
2346 16 : if (!EG(scope)) {
2347 3 : if (error) *error = estrdup("cannot access self:: when no class scope is active");
2348 : } else {
2349 13 : fcc->called_scope = EG(called_scope);
2350 13 : fcc->calling_scope = EG(scope);
2351 13 : if (!fcc->object_ptr) {
2352 10 : fcc->object_ptr = EG(This);
2353 : }
2354 13 : ret = 1;
2355 : }
2356 320 : } else if (name_len == sizeof("parent") - 1 &&
2357 : !memcmp(lcname, "parent", sizeof("parent") - 1)) {
2358 34 : if (!EG(scope)) {
2359 0 : if (error) *error = estrdup("cannot access parent:: when no class scope is active");
2360 34 : } else if (!EG(scope)->parent) {
2361 0 : if (error) *error = estrdup("cannot access parent:: when current class scope has no parent");
2362 : } else {
2363 34 : fcc->called_scope = EG(called_scope);
2364 34 : fcc->calling_scope = EG(scope)->parent;
2365 34 : if (!fcc->object_ptr) {
2366 17 : fcc->object_ptr = EG(This);
2367 : }
2368 34 : ret = 1;
2369 : }
2370 264 : } else if (name_len == sizeof("static") - 1 &&
2371 : !memcmp(lcname, "static", sizeof("static") - 1)) {
2372 12 : if (!EG(called_scope)) {
2373 0 : if (error) *error = estrdup("cannot access static:: when no class scope is active");
2374 : } else {
2375 12 : fcc->called_scope = EG(called_scope);
2376 12 : fcc->calling_scope = EG(called_scope);
2377 12 : if (!fcc->object_ptr) {
2378 11 : fcc->object_ptr = EG(This);
2379 : }
2380 12 : ret = 1;
2381 : }
2382 240 : } else if (zend_lookup_class_ex(name, name_len, 1, &pce TSRMLS_CC) == SUCCESS) {
2383 227 : zend_class_entry *scope = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
2384 :
2385 227 : fcc->calling_scope = *pce;
2386 249 : if (scope && !fcc->object_ptr && EG(This) &&
2387 : instanceof_function(Z_OBJCE_P(EG(This)), scope TSRMLS_CC) &&
2388 : instanceof_function(scope, fcc->calling_scope TSRMLS_CC)) {
2389 22 : fcc->object_ptr = EG(This);
2390 22 : fcc->called_scope = Z_OBJCE_P(fcc->object_ptr);
2391 : } else {
2392 205 : fcc->called_scope = fcc->object_ptr ? Z_OBJCE_P(fcc->object_ptr) : fcc->calling_scope;
2393 : }
2394 227 : ret = 1;
2395 : } else {
2396 12 : if (error) zend_spprintf(error, 0, "class '%.*s' not found", name_len, name);
2397 : }
2398 301 : efree(lcname);
2399 301 : return ret;
2400 : }
2401 : /* }}} */
2402 :
2403 :
2404 : static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
2405 230777 : {
2406 230777 : zend_class_entry *ce_org = fcc->calling_scope;
2407 230777 : int retval = 0;
2408 : char *mname, *lmname, *colon;
2409 : int clen, mlen;
2410 : zend_class_entry *last_scope;
2411 : HashTable *ftable;
2412 230777 : int call_via_handler = 0;
2413 :
2414 230777 : if (error) {
2415 230065 : *error = NULL;
2416 : }
2417 :
2418 230777 : fcc->calling_scope = NULL;
2419 230777 : fcc->function_handler = NULL;
2420 :
2421 230777 : if (!ce_org) {
2422 : /* Skip leading \ */
2423 222296 : if (Z_STRVAL_P(callable)[0] == '\\') {
2424 20 : mlen = Z_STRLEN_P(callable) - 1;
2425 20 : mname = Z_STRVAL_P(callable) + 1;
2426 20 : lmname = zend_str_tolower_dup(Z_STRVAL_P(callable) + 1, mlen);
2427 : } else {
2428 222276 : mlen = Z_STRLEN_P(callable);
2429 222276 : mname = Z_STRVAL_P(callable);
2430 222276 : lmname = zend_str_tolower_dup(Z_STRVAL_P(callable), mlen);
2431 : }
2432 : /* Check if function with given name exists.
2433 : * This may be a compound name that includes namespace name */
2434 222296 : if (zend_hash_find(EG(function_table), lmname, mlen+1, (void**)&fcc->function_handler) == SUCCESS) {
2435 221861 : efree(lmname);
2436 221861 : return 1;
2437 : }
2438 435 : efree(lmname);
2439 : }
2440 :
2441 : /* Split name into class/namespace and method/function names */
2442 9031 : if ((colon = zend_memrchr(Z_STRVAL_P(callable), ':', Z_STRLEN_P(callable))) != NULL &&
2443 : colon > Z_STRVAL_P(callable) &&
2444 : *(colon-1) == ':'
2445 : ) {
2446 120 : colon--;
2447 120 : clen = colon - Z_STRVAL_P(callable);
2448 120 : mlen = Z_STRLEN_P(callable) - clen - 2;
2449 :
2450 120 : if (colon == Z_STRVAL_P(callable)) {
2451 0 : if (error) zend_spprintf(error, 0, "invalid function name");
2452 0 : return 0;
2453 : }
2454 :
2455 : /* This is a compound name.
2456 : * Try to fetch class and then find static method. */
2457 120 : last_scope = EG(scope);
2458 120 : if (ce_org) {
2459 27 : EG(scope) = ce_org;
2460 : }
2461 :
2462 120 : if (!zend_is_callable_check_class(Z_STRVAL_P(callable), clen, fcc, error TSRMLS_CC)) {
2463 3 : EG(scope) = last_scope;
2464 3 : return 0;
2465 : }
2466 116 : EG(scope) = last_scope;
2467 :
2468 116 : ftable = &fcc->calling_scope->function_table;
2469 116 : if (ce_org && !instanceof_function(ce_org, fcc->calling_scope TSRMLS_CC)) {
2470 1 : if (error) zend_spprintf(error, 0, "class '%s' is not a subclass of '%s'", ce_org->name, fcc->calling_scope->name);
2471 1 : return 0;
2472 : }
2473 115 : mname = Z_STRVAL_P(callable) + clen + 2;
2474 8796 : } else if (ce_org) {
2475 : /* Try to fetch find static method of given class. */
2476 8454 : mlen = Z_STRLEN_P(callable);
2477 8454 : mname = Z_STRVAL_P(callable);
2478 8454 : ftable = &ce_org->function_table;
2479 8454 : fcc->calling_scope = ce_org;
2480 : } else {
2481 : /* We already checked for plain function before. */
2482 342 : if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) {
2483 184 : zend_spprintf(error, 0, "function '%s' not found or invalid function name", Z_STRVAL_P(callable));
2484 : }
2485 342 : return 0;
2486 : }
2487 :
2488 8569 : lmname = zend_str_tolower_dup(mname, mlen);
2489 8569 : if (zend_hash_find(ftable, lmname, mlen+1, (void**)&fcc->function_handler) == SUCCESS) {
2490 8321 : retval = 1;
2491 8321 : if ((fcc->function_handler->op_array.fn_flags & ZEND_ACC_CHANGED) &&
2492 : EG(scope) &&
2493 : instanceof_function(fcc->function_handler->common.scope, EG(scope) TSRMLS_CC)) {
2494 : zend_function *priv_fbc;
2495 :
2496 1 : if (zend_hash_find(&EG(scope)->function_table, lmname, mlen+1, (void **) &priv_fbc)==SUCCESS
2497 : && priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
2498 : && priv_fbc->common.scope == EG(scope)) {
2499 1 : fcc->function_handler = priv_fbc;
2500 : }
2501 : }
2502 8321 : if ((check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0 &&
2503 : (fcc->calling_scope &&
2504 : (fcc->calling_scope->__call ||
2505 : fcc->calling_scope->__callstatic))) {
2506 408 : if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
2507 2 : if (!zend_check_private(fcc->function_handler, fcc->object_ptr ? Z_OBJCE_P(fcc->object_ptr) : EG(scope), lmname, mlen TSRMLS_CC)) {
2508 1 : retval = 0;
2509 1 : fcc->function_handler = NULL;
2510 1 : goto get_function_via_handler;
2511 : }
2512 406 : } else if (fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED) {
2513 2 : if (!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) {
2514 1 : retval = 0;
2515 1 : fcc->function_handler = NULL;
2516 1 : goto get_function_via_handler;
2517 : }
2518 : }
2519 : }
2520 : } else {
2521 250 : get_function_via_handler:
2522 474 : if (fcc->object_ptr && fcc->calling_scope == ce_org) {
2523 224 : if (Z_OBJ_HT_P(fcc->object_ptr)->get_method) {
2524 224 : fcc->function_handler = Z_OBJ_HT_P(fcc->object_ptr)->get_method(&fcc->object_ptr, mname, mlen TSRMLS_CC);
2525 224 : if (fcc->function_handler) {
2526 23 : retval = 1;
2527 23 : call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
2528 : }
2529 : }
2530 26 : } else if (fcc->calling_scope) {
2531 26 : if (fcc->calling_scope->get_static_method) {
2532 0 : fcc->function_handler = fcc->calling_scope->get_static_method(fcc->calling_scope, mname, mlen TSRMLS_CC);
2533 : } else {
2534 26 : fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, mname, mlen TSRMLS_CC);
2535 : }
2536 26 : if (fcc->function_handler) {
2537 11 : retval = 1;
2538 11 : call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
2539 : }
2540 : }
2541 : }
2542 :
2543 8569 : if (retval) {
2544 8353 : if (fcc->calling_scope && !call_via_handler) {
2545 8319 : if (!fcc->object_ptr && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) {
2546 : int severity;
2547 : char *verb;
2548 45 : if (fcc->function_handler->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
2549 43 : severity = E_STRICT;
2550 43 : verb = "should not";
2551 : } else {
2552 : /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
2553 2 : severity = E_ERROR;
2554 2 : verb = "cannot";
2555 : }
2556 45 : if ((check_flags & IS_CALLABLE_CHECK_IS_STATIC) != 0) {
2557 5 : retval = 0;
2558 : }
2559 45 : if (EG(This) && instanceof_function(Z_OBJCE_P(EG(This)), fcc->calling_scope TSRMLS_CC)) {
2560 0 : fcc->object_ptr = EG(This);
2561 0 : if (error) {
2562 0 : zend_spprintf(error, 0, "non-static method %s::%s() %s be called statically, assuming $this from compatible context %s", fcc->calling_scope->name, fcc->function_handler->common.function_name, verb, Z_OBJCE_P(EG(This))->name);
2563 0 : if (severity == E_ERROR) {
2564 0 : retval = 0;
2565 : }
2566 0 : } else if (retval) {
2567 0 : zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from compatible context %s", fcc->calling_scope->name, fcc->function_handler->common.function_name, verb, Z_OBJCE_P(EG(This))->name);
2568 : }
2569 : } else {
2570 45 : if (error) {
2571 41 : zend_spprintf(error, 0, "non-static method %s::%s() %s be called statically", fcc->calling_scope->name, fcc->function_handler->common.function_name, verb);
2572 41 : if (severity == E_ERROR) {
2573 1 : retval = 0;
2574 : }
2575 4 : } else if (retval) {
2576 4 : zend_error(severity, "Non-static method %s::%s() %s be called statically", fcc->calling_scope->name, fcc->function_handler->common.function_name, verb);
2577 : }
2578 : }
2579 : }
2580 8318 : if (retval && (check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) {
2581 8309 : if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
2582 27 : if (!zend_check_private(fcc->function_handler, fcc->object_ptr ? Z_OBJCE_P(fcc->object_ptr) : EG(scope), lmname, mlen TSRMLS_CC)) {
2583 18 : if (error) {
2584 18 : if (*error) {
2585 1 : efree(*error);
2586 : }
2587 18 : zend_spprintf(error, 0, "cannot access private method %s::%s()", fcc->calling_scope->name, fcc->function_handler->common.function_name);
2588 : }
2589 18 : retval = 0;
2590 : }
2591 8282 : } else if ((fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED)) {
2592 25 : if (!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) {
2593 18 : if (error) {
2594 18 : if (*error) {
2595 1 : efree(*error);
2596 : }
2597 18 : zend_spprintf(error, 0, "cannot access protected method %s::%s()", fcc->calling_scope->name, fcc->function_handler->common.function_name);
2598 : }
2599 18 : retval = 0;
2600 : }
2601 : }
2602 : }
2603 : }
2604 216 : } else if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) {
2605 127 : if (fcc->calling_scope) {
2606 127 : if (error) zend_spprintf(error, 0, "class '%s' does not have a method '%s'", fcc->calling_scope->name, mname);
2607 : } else {
2608 0 : if (error) zend_spprintf(error, 0, "function '%s' does not exist", mname);
2609 : }
2610 : }
2611 8568 : efree(lmname);
2612 :
2613 8568 : if (fcc->object_ptr) {
2614 8342 : fcc->called_scope = Z_OBJCE_P(fcc->object_ptr);
2615 : }
2616 8568 : if (retval) {
2617 8310 : fcc->initialized = 1;
2618 : }
2619 8568 : return retval;
2620 : }
2621 : /* }}} */
2622 :
2623 : ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint check_flags, char **callable_name, int *callable_name_len, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
2624 231878 : {
2625 : zend_bool ret;
2626 : int callable_name_len_local;
2627 : zend_fcall_info_cache fcc_local;
2628 :
2629 231878 : if (callable_name) {
2630 227873 : *callable_name = NULL;
2631 : }
2632 231878 : if (callable_name_len == NULL) {
2633 231801 : callable_name_len = &callable_name_len_local;
2634 : }
2635 231878 : if (fcc == NULL) {
2636 1379 : fcc = &fcc_local;
2637 : }
2638 231878 : if (error) {
2639 231085 : *error = NULL;
2640 : }
2641 :
2642 231878 : fcc->initialized = 0;
2643 231878 : fcc->calling_scope = NULL;
2644 231878 : fcc->called_scope = NULL;
2645 231878 : fcc->function_handler = NULL;
2646 231878 : fcc->calling_scope = NULL;
2647 231878 : fcc->object_ptr = NULL;
2648 :
2649 231878 : if (object_ptr && Z_TYPE_P(object_ptr) != IS_OBJECT) {
2650 0 : object_ptr = NULL;
2651 : }
2652 231878 : if (object_ptr &&
2653 : (!EG(objects_store).object_buckets ||
2654 : !EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(object_ptr)].valid)) {
2655 2 : return 0;
2656 : }
2657 :
2658 231876 : switch (Z_TYPE_P(callable)) {
2659 : case IS_STRING:
2660 230227 : if (object_ptr) {
2661 7876 : fcc->object_ptr = object_ptr;
2662 7876 : fcc->calling_scope = Z_OBJCE_P(object_ptr);
2663 7876 : if (callable_name) {
2664 : char *ptr;
2665 :
2666 7876 : *callable_name_len = fcc->calling_scope->name_length + Z_STRLEN_P(callable) + sizeof("::") - 1;
2667 7876 : ptr = *callable_name = emalloc(*callable_name_len + 1);
2668 7876 : memcpy(ptr, fcc->calling_scope->name, fcc->calling_scope->name_length);
2669 7876 : ptr += fcc->calling_scope->name_length;
2670 7876 : memcpy(ptr, "::", sizeof("::") - 1);
2671 7876 : ptr += sizeof("::") - 1;
2672 7876 : memcpy(ptr, Z_STRVAL_P(callable), Z_STRLEN_P(callable) + 1);
2673 : }
2674 222351 : } else if (callable_name) {
2675 219417 : *callable_name = estrndup(Z_STRVAL_P(callable), Z_STRLEN_P(callable));
2676 219417 : *callable_name_len = Z_STRLEN_P(callable);
2677 : }
2678 230227 : if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
2679 55 : fcc->called_scope = fcc->calling_scope;
2680 55 : return 1;
2681 : }
2682 :
2683 230172 : ret = zend_is_callable_check_func(check_flags, callable, fcc, error TSRMLS_CC);
2684 230171 : if (fcc == &fcc_local &&
2685 : fcc->function_handler &&
2686 : ((fcc->function_handler->type == ZEND_INTERNAL_FUNCTION &&
2687 : (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
2688 : fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
2689 : fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
2690 0 : if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
2691 0 : efree(fcc->function_handler->common.function_name);
2692 : }
2693 0 : efree(fcc->function_handler);
2694 : }
2695 230171 : return ret;
2696 :
2697 : case IS_ARRAY:
2698 : {
2699 945 : zval **method = NULL;
2700 945 : zval **obj = NULL;
2701 :
2702 945 : if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
2703 868 : zend_hash_index_find(Z_ARRVAL_P(callable), 0, (void **) &obj);
2704 868 : zend_hash_index_find(Z_ARRVAL_P(callable), 1, (void **) &method);
2705 : }
2706 945 : if (obj && method &&
2707 : (Z_TYPE_PP(obj) == IS_OBJECT ||
2708 : Z_TYPE_PP(obj) == IS_STRING) &&
2709 : Z_TYPE_PP(method) == IS_STRING) {
2710 :
2711 751 : if (Z_TYPE_PP(obj) == IS_STRING) {
2712 200 : if (callable_name) {
2713 : char *ptr;
2714 :
2715 69 : *callable_name_len = Z_STRLEN_PP(obj) + Z_STRLEN_PP(method) + sizeof("::") - 1;
2716 69 : ptr = *callable_name = emalloc(*callable_name_len + 1);
2717 69 : memcpy(ptr, Z_STRVAL_PP(obj), Z_STRLEN_PP(obj));
2718 69 : ptr += Z_STRLEN_PP(obj);
2719 69 : memcpy(ptr, "::", sizeof("::") - 1);
2720 69 : ptr += sizeof("::") - 1;
2721 69 : memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1);
2722 : }
2723 :
2724 200 : if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
2725 18 : return 1;
2726 : }
2727 :
2728 182 : if (!zend_is_callable_check_class(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), fcc, error TSRMLS_CC)) {
2729 12 : return 0;
2730 : }
2731 :
2732 : } else {
2733 551 : if (!EG(objects_store).object_buckets ||
2734 : !EG(objects_store).object_buckets[Z_OBJ_HANDLE_PP(obj)].valid) {
2735 0 : return 0;
2736 : }
2737 :
2738 551 : fcc->calling_scope = Z_OBJCE_PP(obj); /* TBFixed: what if it's overloaded? */
2739 :
2740 551 : fcc->object_ptr = *obj;
2741 :
2742 551 : if (callable_name) {
2743 : char *ptr;
2744 :
2745 294 : *callable_name_len = fcc->calling_scope->name_length + Z_STRLEN_PP(method) + sizeof("::") - 1;
2746 294 : ptr = *callable_name = emalloc(*callable_name_len + 1);
2747 294 : memcpy(ptr, fcc->calling_scope->name, fcc->calling_scope->name_length);
2748 294 : ptr += fcc->calling_scope->name_length;
2749 294 : memcpy(ptr, "::", sizeof("::") - 1);
2750 294 : ptr += sizeof("::") - 1;
2751 294 : memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1);
2752 : }
2753 :
2754 551 : if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
2755 116 : fcc->called_scope = fcc->calling_scope;
2756 116 : return 1;
2757 : }
2758 : }
2759 :
2760 605 : ret = zend_is_callable_check_func(check_flags, *method, fcc, error TSRMLS_CC);
2761 604 : if (fcc == &fcc_local &&
2762 : fcc->function_handler &&
2763 : ((fcc->function_handler->type == ZEND_INTERNAL_FUNCTION &&
2764 : (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
2765 : fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
2766 : fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
2767 1 : if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
2768 1 : efree(fcc->function_handler->common.function_name);
2769 : }
2770 1 : efree(fcc->function_handler);
2771 : }
2772 604 : return ret;
2773 :
2774 : } else {
2775 194 : if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
2776 232 : if (!obj || (Z_TYPE_PP(obj) != IS_STRING && Z_TYPE_PP(obj) != IS_OBJECT)) {
2777 115 : if (error) zend_spprintf(error, 0, "first array member is not a valid class name or object");
2778 : } else {
2779 2 : if (error) zend_spprintf(error, 0, "second array member is not a valid method");
2780 : }
2781 : } else {
2782 77 : if (error) zend_spprintf(error, 0, "array must have exactly two members");
2783 : }
2784 194 : if (callable_name) {
2785 46 : *callable_name = estrndup("Array", sizeof("Array")-1);
2786 46 : *callable_name_len = sizeof("Array") - 1;
2787 : }
2788 : }
2789 : }
2790 194 : return 0;
2791 :
2792 : case IS_OBJECT:
2793 187 : if (Z_OBJ_HANDLER_P(callable, get_closure) && Z_OBJ_HANDLER_P(callable, get_closure)(callable, &fcc->calling_scope, &fcc->function_handler, &fcc->object_ptr TSRMLS_CC) == SUCCESS) {
2794 135 : fcc->called_scope = fcc->calling_scope;
2795 135 : if (callable_name) {
2796 125 : zend_class_entry *ce = Z_OBJCE_P(callable); /* TBFixed: what if it's overloaded? */
2797 :
2798 125 : *callable_name_len = ce->name_length + sizeof("::__invoke") - 1;
2799 125 : *callable_name = emalloc(*callable_name_len + 1);
2800 125 : memcpy(*callable_name, ce->name, ce->name_length);
2801 125 : memcpy((*callable_name) + ce->name_length, "::__invoke", sizeof("::__invoke"));
2802 : }
2803 135 : return 1;
2804 : }
2805 : /* break missing intentionally */
2806 :
2807 : default:
2808 569 : if (callable_name) {
2809 : zval expr_copy;
2810 : int use_copy;
2811 :
2812 44 : zend_make_printable_zval(callable, &expr_copy, &use_copy);
2813 42 : *callable_name = estrndup(Z_STRVAL(expr_copy), Z_STRLEN(expr_copy));
2814 42 : *callable_name_len = Z_STRLEN(expr_copy);
2815 42 : zval_dtor(&expr_copy);
2816 : }
2817 567 : if (error) zend_spprintf(error, 0, "no array or string given");
2818 567 : return 0;
2819 : }
2820 : }
2821 : /* }}} */
2822 :
2823 : ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **callable_name TSRMLS_DC) /* {{{ */
2824 749 : {
2825 749 : return zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, NULL, NULL TSRMLS_CC);
2826 : }
2827 : /* }}} */
2828 :
2829 : ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRMLS_DC) /* {{{ */
2830 24 : {
2831 : zend_fcall_info_cache fcc;
2832 :
2833 24 : if (zend_is_callable_ex(callable, NULL, IS_CALLABLE_STRICT, callable_name, NULL, &fcc, NULL TSRMLS_CC)) {
2834 21 : if (Z_TYPE_P(callable) == IS_STRING && fcc.calling_scope) {
2835 4 : zval_dtor(callable);
2836 4 : array_init(callable);
2837 4 : add_next_index_string(callable, fcc.calling_scope->name, 1);
2838 4 : add_next_index_string(callable, fcc.function_handler->common.function_name, 1);
2839 : }
2840 21 : if (fcc.function_handler &&
2841 : ((fcc.function_handler->type == ZEND_INTERNAL_FUNCTION &&
2842 : (fcc.function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
2843 : fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
2844 : fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
2845 0 : if (fcc.function_handler->type != ZEND_OVERLOADED_FUNCTION) {
2846 0 : efree(fcc.function_handler->common.function_name);
2847 : }
2848 0 : efree(fcc.function_handler);
2849 : }
2850 21 : return 1;
2851 : }
2852 2 : return 0;
2853 : }
2854 : /* }}} */
2855 :
2856 : ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, char **callable_name, char **error TSRMLS_DC) /* {{{ */
2857 3474 : {
2858 3474 : if (!zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, fcc, error TSRMLS_CC)) {
2859 733 : return FAILURE;
2860 : }
2861 :
2862 2741 : fci->size = sizeof(*fci);
2863 2741 : fci->function_table = fcc->calling_scope ? &fcc->calling_scope->function_table : EG(function_table);
2864 2741 : fci->object_ptr = fcc->object_ptr;
2865 2741 : fci->function_name = callable;
2866 2741 : fci->retval_ptr_ptr = NULL;
2867 2741 : fci->param_count = 0;
2868 2741 : fci->params = NULL;
2869 2741 : fci->no_separation = 1;
2870 2741 : fci->symbol_table = NULL;
2871 :
2872 2741 : return SUCCESS;
2873 : }
2874 : /* }}} */
2875 :
2876 : ZEND_API void zend_fcall_info_args_clear(zend_fcall_info *fci, int free_mem) /* {{{ */
2877 208 : {
2878 208 : if (fci->params) {
2879 99 : if (free_mem) {
2880 99 : efree(fci->params);
2881 99 : fci->params = NULL;
2882 : }
2883 : }
2884 208 : fci->param_count = 0;
2885 208 : }
2886 : /* }}} */
2887 :
2888 : ZEND_API void zend_fcall_info_args_save(zend_fcall_info *fci, int *param_count, zval ****params) /* {{{ */
2889 0 : {
2890 0 : *param_count = fci->param_count;
2891 0 : *params = fci->params;
2892 0 : fci->param_count = 0;
2893 0 : fci->params = NULL;
2894 0 : }
2895 : /* }}} */
2896 :
2897 : ZEND_API void zend_fcall_info_args_restore(zend_fcall_info *fci, int param_count, zval ***params) /* {{{ */
2898 0 : {
2899 0 : zend_fcall_info_args_clear(fci, 1);
2900 0 : fci->param_count = param_count;
2901 0 : fci->params = params;
2902 0 : }
2903 : /* }}} */
2904 :
2905 : ZEND_API int zend_fcall_info_args(zend_fcall_info *fci, zval *args TSRMLS_DC) /* {{{ */
2906 110 : {
2907 : HashPosition pos;
2908 : zval **arg, ***params;
2909 :
2910 110 : zend_fcall_info_args_clear(fci, !args);
2911 :
2912 110 : if (!args) {
2913 11 : return SUCCESS;
2914 : }
2915 :
2916 99 : if (Z_TYPE_P(args) != IS_ARRAY) {
2917 0 : return FAILURE;
2918 : }
2919 :
2920 99 : fci->param_count = zend_hash_num_elements(Z_ARRVAL_P(args));
2921 99 : fci->params = params = (zval ***) erealloc(fci->params, fci->param_count * sizeof(zval **));
2922 :
2923 99 : zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(args), &pos);
2924 1452 : while (zend_hash_get_current_data_ex(Z_ARRVAL_P(args), (void *) &arg, &pos) == SUCCESS) {
2925 1254 : *params++ = arg;
2926 1254 : zend_hash_move_forward_ex(Z_ARRVAL_P(args), &pos);
2927 : }
2928 :
2929 99 : return SUCCESS;
2930 : }
2931 : /* }}} */
2932 :
2933 : ZEND_API int zend_fcall_info_argp(zend_fcall_info *fci TSRMLS_DC, int argc, zval ***argv) /* {{{ */
2934 0 : {
2935 : int i;
2936 :
2937 0 : if (argc < 0) {
2938 0 : return FAILURE;
2939 : }
2940 :
2941 0 : zend_fcall_info_args_clear(fci, !argc);
2942 :
2943 0 : if (argc) {
2944 0 : fci->param_count = argc;
2945 0 : fci->params = (zval ***) erealloc(fci->params, fci->param_count * sizeof(zval **));
2946 :
2947 0 : for (i = 0; i < argc; ++i) {
2948 0 : fci->params[i] = argv[i];
2949 : }
2950 : }
2951 :
2952 0 : return SUCCESS;
2953 : }
2954 : /* }}} */
2955 :
2956 : ZEND_API int zend_fcall_info_argv(zend_fcall_info *fci TSRMLS_DC, int argc, va_list *argv) /* {{{ */
2957 0 : {
2958 : int i;
2959 : zval **arg;
2960 :
2961 0 : if (argc < 0) {
2962 0 : return FAILURE;
2963 : }
2964 :
2965 0 : zend_fcall_info_args_clear(fci, !argc);
2966 :
2967 0 : if (argc) {
2968 0 : fci->param_count = argc;
2969 0 : fci->params = (zval ***) erealloc(fci->params, fci->param_count * sizeof(zval **));
2970 :
2971 0 : for (i = 0; i < argc; ++i) {
2972 0 : arg = va_arg(*argv, zval **);
2973 0 : fci->params[i] = arg;
2974 : }
2975 : }
2976 :
2977 0 : return SUCCESS;
2978 : }
2979 : /* }}} */
2980 :
2981 : ZEND_API int zend_fcall_info_argn(zend_fcall_info *fci TSRMLS_DC, int argc, ...) /* {{{ */
2982 0 : {
2983 : int ret;
2984 : va_list argv;
2985 :
2986 0 : va_start(argv, argc);
2987 0 : ret = zend_fcall_info_argv(fci TSRMLS_CC, argc, &argv);
2988 0 : va_end(argv);
2989 :
2990 0 : return ret;
2991 : }
2992 : /* }}} */
2993 :
2994 : ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval **retval_ptr_ptr, zval *args TSRMLS_DC) /* {{{ */
2995 14 : {
2996 14 : zval *retval, ***org_params = NULL;
2997 14 : int result, org_count = 0;
2998 :
2999 14 : fci->retval_ptr_ptr = retval_ptr_ptr ? retval_ptr_ptr : &retval;
3000 14 : if (args) {
3001 0 : zend_fcall_info_args_save(fci, &org_count, &org_params);
3002 0 : zend_fcall_info_args(fci, args TSRMLS_CC);
3003 : }
3004 14 : result = zend_call_function(fci, fcc TSRMLS_CC);
3005 :
3006 14 : if (!retval_ptr_ptr && retval) {
3007 0 : zval_ptr_dtor(&retval);
3008 : }
3009 14 : if (args) {
3010 0 : zend_fcall_info_args_restore(fci, org_count, org_params);
3011 : }
3012 14 : return result;
3013 : }
3014 : /* }}} */
3015 :
3016 : ZEND_API const char *zend_get_module_version(const char *module_name) /* {{{ */
3017 0 : {
3018 : char *lname;
3019 0 : int name_len = strlen(module_name);
3020 : zend_module_entry *module;
3021 :
3022 0 : lname = zend_str_tolower_dup(module_name, name_len);
3023 0 : if (zend_hash_find(&module_registry, lname, name_len + 1, (void**)&module) == FAILURE) {
3024 0 : efree(lname);
3025 0 : return NULL;
3026 : }
3027 0 : efree(lname);
3028 0 : return module->version;
3029 : }
3030 : /* }}} */
3031 :
3032 : ZEND_API int zend_declare_property_ex(zend_class_entry *ce, const char *name, int name_length, zval *property, int access_type, char *doc_comment, int doc_comment_len TSRMLS_DC) /* {{{ */
3033 1148042 : {
3034 : zend_property_info property_info;
3035 : HashTable *target_symbol_table;
3036 :
3037 1148042 : if (!(access_type & ZEND_ACC_PPP_MASK)) {
3038 35328 : access_type |= ZEND_ACC_PUBLIC;
3039 : }
3040 1148042 : if (access_type & ZEND_ACC_STATIC) {
3041 309 : target_symbol_table = &ce->default_static_members;
3042 : } else {
3043 1147733 : target_symbol_table = &ce->default_properties;
3044 : }
3045 1148042 : if (ce->type & ZEND_INTERNAL_CLASS) {
3046 1146145 : switch(Z_TYPE_P(property)) {
3047 : case IS_ARRAY:
3048 : case IS_CONSTANT_ARRAY:
3049 : case IS_OBJECT:
3050 : case IS_RESOURCE:
3051 0 : zend_error(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
3052 : break;
3053 : default:
3054 : break;
3055 : }
3056 : }
3057 1148042 : switch (access_type & ZEND_ACC_PPP_MASK) {
3058 : case ZEND_ACC_PRIVATE: {
3059 : char *priv_name;
3060 : int priv_name_length;
3061 :
3062 53325 : zend_mangle_property_name(&priv_name, &priv_name_length, ce->name, ce->name_length, name, name_length, ce->type & ZEND_INTERNAL_CLASS);
3063 53325 : zend_hash_update(target_symbol_table, priv_name, priv_name_length+1, &property, sizeof(zval *), NULL);
3064 53325 : property_info.name = priv_name;
3065 53325 : property_info.name_length = priv_name_length;
3066 : }
3067 53325 : break;
3068 : case ZEND_ACC_PROTECTED: {
3069 : char *prot_name;
3070 : int prot_name_length;
3071 :
3072 123790 : zend_mangle_property_name(&prot_name, &prot_name_length, "*", 1, name, name_length, ce->type & ZEND_INTERNAL_CLASS);
3073 123790 : zend_hash_update(target_symbol_table, prot_name, prot_name_length+1, &property, sizeof(zval *), NULL);
3074 123790 : property_info.name = prot_name;
3075 123790 : property_info.name_length = prot_name_length;
3076 : }
3077 123790 : break;
3078 : case ZEND_ACC_PUBLIC:
3079 970927 : if (ce->parent) {
3080 : char *prot_name;
3081 : int prot_name_length;
3082 :
3083 105798 : zend_mangle_property_name(&prot_name, &prot_name_length, "*", 1, name, name_length, ce->type & ZEND_INTERNAL_CLASS);
3084 105798 : zend_hash_del(target_symbol_table, prot_name, prot_name_length+1);
3085 105798 : pefree(prot_name, ce->type & ZEND_INTERNAL_CLASS);
3086 : }
3087 970927 : zend_hash_update(target_symbol_table, name, name_length+1, &property, sizeof(zval *), NULL);
3088 970927 : property_info.name = ce->type & ZEND_INTERNAL_CLASS ? zend_strndup(name, name_length) : estrndup(name, name_length);
3089 970927 : property_info.name_length = name_length;
3090 : break;
3091 : }
3092 1148042 : property_info.flags = access_type;
3093 1148042 : property_info.h = zend_get_hash_value(property_info.name, property_info.name_length+1);
3094 :
3095 1148042 : property_info.doc_comment = doc_comment;
3096 1148042 : property_info.doc_comment_len = doc_comment_len;
3097 :
3098 1148042 : property_info.ce = ce;
3099 :
3100 1148042 : zend_hash_update(&ce->properties_info, name, name_length + 1, &property_info, sizeof(zend_property_info), NULL);
3101 :
3102 1148042 : return SUCCESS;
3103 : }
3104 : /* }}} */
3105 :
3106 : ZEND_API int zend_declare_property(zend_class_entry *ce, char *name, int name_length, zval *property, int access_type TSRMLS_DC) /* {{{ */
3107 1146145 : {
3108 1146145 : return zend_declare_property_ex(ce, name, name_length, property, access_type, NULL, 0 TSRMLS_CC);
3109 : }
3110 : /* }}} */
3111 :
3112 : ZEND_API int zend_declare_property_null(zend_class_entry *ce, char *name, int name_length, int access_type TSRMLS_DC) /* {{{ */
3113 828751 : {
3114 : zval *property;
3115 :
3116 828751 : if (ce->type & ZEND_INTERNAL_CLASS) {
3117 828751 : ALLOC_PERMANENT_ZVAL(property);
3118 : } else {
3119 0 : ALLOC_ZVAL(property);
3120 : }
3121 828751 : INIT_ZVAL(*property);
3122 828751 : return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
3123 : }
3124 : /* }}} */
3125 :
3126 : ZEND_API int zend_declare_property_bool(zend_class_entry *ce, char *name, int name_length, long value, int access_type TSRMLS_DC) /* {{{ */
3127 0 : {
3128 : zval *property;
3129 :
3130 0 : if (ce->type & ZEND_INTERNAL_CLASS) {
3131 0 : ALLOC_PERMANENT_ZVAL(property);
3132 : } else {
3133 0 : ALLOC_ZVAL(property);
3134 : }
3135 0 : INIT_PZVAL(property);
3136 0 : ZVAL_BOOL(property, value);
3137 0 : return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
3138 : }
3139 : /* }}} */
3140 :
3141 : ZEND_API int zend_declare_property_long(zend_class_entry *ce, char *name, int name_length, long value, int access_type TSRMLS_DC) /* {{{ */
3142 70532 : {
3143 : zval *property;
3144 :
3145 70532 : if (ce->type & ZEND_INTERNAL_CLASS) {
3146 70532 : ALLOC_PERMANENT_ZVAL(property);
3147 : } else {
3148 0 : ALLOC_ZVAL(property);
3149 : }
3150 70532 : INIT_PZVAL(property);
3151 70532 : ZVAL_LONG(property, value);
3152 70532 : return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
3153 : }
3154 : /* }}} */
3155 :
3156 : ZEND_API int zend_declare_property_double(zend_class_entry *ce, char *name, int name_length, double value, int access_type TSRMLS_DC) /* {{{ */
3157 0 : {
3158 : zval *property;
3159 :
3160 0 : if (ce->type & ZEND_INTERNAL_CLASS) {
3161 0 : ALLOC_PERMANENT_ZVAL(property);
3162 : } else {
3163 0 : ALLOC_ZVAL(property);
3164 : }
3165 0 : INIT_PZVAL(property);
3166 0 : ZVAL_DOUBLE(property, value);
3167 0 : return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
3168 : }
3169 : /* }}} */
3170 :
3171 : ZEND_API int zend_declare_property_string(zend_class_entry *ce, char *name, int name_length, char *value, int access_type TSRMLS_DC) /* {{{ */
3172 246862 : {
3173 : zval *property;
3174 246862 : int len = strlen(value);
3175 :
3176 246862 : if (ce->type & ZEND_INTERNAL_CLASS) {
3177 246862 : ALLOC_PERMANENT_ZVAL(property);
3178 246862 : ZVAL_STRINGL(property, zend_strndup(value, len), len, 0);
3179 : } else {
3180 0 : ALLOC_ZVAL(property);
3181 0 : ZVAL_STRINGL(property, value, len, 1);
3182 : }
3183 246862 : INIT_PZVAL(property);
3184 246862 : return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
3185 : }
3186 : /* }}} */
3187 :
3188 : ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, char *name, int name_length, char *value, int value_len, int access_type TSRMLS_DC) /* {{{ */
3189 0 : {
3190 : zval *property;
3191 :
3192 0 : if (ce->type & ZEND_INTERNAL_CLASS) {
3193 0 : ALLOC_PERMANENT_ZVAL(property);
3194 0 : ZVAL_STRINGL(property, zend_strndup(value, value_len), value_len, 0);
3195 : } else {
3196 0 : ALLOC_ZVAL(property);
3197 0 : ZVAL_STRINGL(property, value, value_len, 1);
3198 : }
3199 0 : INIT_PZVAL(property);
3200 0 : return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
3201 : }
3202 : /* }}} */
3203 :
3204 : ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value TSRMLS_DC) /* {{{ */
3205 6647641 : {
3206 6647641 : return zend_hash_update(&ce->constants_table, name, name_length+1, &value, sizeof(zval *), NULL);
3207 : }
3208 : /* }}} */
3209 :
3210 : ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, const char *name, size_t name_length TSRMLS_DC) /* {{{ */
3211 17633 : {
3212 : zval *constant;
3213 :
3214 17633 : if (ce->type & ZEND_INTERNAL_CLASS) {
3215 17633 : ALLOC_PERMANENT_ZVAL(constant);
3216 : } else {
3217 0 : ALLOC_ZVAL(constant);
3218 : }
3219 17633 : ZVAL_NULL(constant);
3220 17633 : INIT_PZVAL(constant);
3221 17633 : return zend_declare_class_constant(ce, name, name_length, constant TSRMLS_CC);
3222 : }
3223 : /* }}} */
3224 :
3225 : ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, const char *name, size_t name_length, long value TSRMLS_DC) /* {{{ */
3226 6294981 : {
3227 : zval *constant;
3228 :
3229 6294981 : if (ce->type & ZEND_INTERNAL_CLASS) {
3230 6294981 : ALLOC_PERMANENT_ZVAL(constant);
3231 : } else {
3232 0 : ALLOC_ZVAL(constant);
3233 : }
3234 6294981 : ZVAL_LONG(constant, value);
3235 6294981 : INIT_PZVAL(constant);
3236 6294981 : return zend_declare_class_constant(ce, name, name_length, constant TSRMLS_CC);
3237 : }
3238 : /* }}} */
3239 :
3240 : ZEND_API int zend_declare_class_constant_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_bool value TSRMLS_DC) /* {{{ */
3241 0 : {
3242 : zval *constant;
3243 :
3244 0 : if (ce->type & ZEND_INTERNAL_CLASS) {
3245 0 : ALLOC_PERMANENT_ZVAL(constant);
3246 : } else {
3247 0 : ALLOC_ZVAL(constant);
3248 : }
3249 0 : ZVAL_BOOL(constant, value);
3250 0 : INIT_PZVAL(constant);
3251 0 : return zend_declare_class_constant(ce, name, name_length, constant TSRMLS_CC);
3252 : }
3253 : /* }}} */
3254 :
3255 : ZEND_API int zend_declare_class_constant_double(zend_class_entry *ce, const char *name, size_t name_length, double value TSRMLS_DC) /* {{{ */
3256 0 : {
3257 : zval *constant;
3258 :
3259 0 : if (ce->type & ZEND_INTERNAL_CLASS) {
3260 0 : ALLOC_PERMANENT_ZVAL(constant);
3261 : } else {
3262 0 : ALLOC_ZVAL(constant);
3263 : }
3264 0 : ZVAL_DOUBLE(constant, value);
3265 0 : INIT_PZVAL(constant);
3266 0 : return zend_declare_class_constant(ce, name, name_length, constant TSRMLS_CC);
3267 : }
3268 : /* }}} */
3269 :
3270 : 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 TSRMLS_DC) /* {{{ */
3271 335027 : {
3272 : zval *constant;
3273 :
3274 335027 : if (ce->type & ZEND_INTERNAL_CLASS) {
3275 335027 : ALLOC_PERMANENT_ZVAL(constant);
3276 335027 : ZVAL_STRINGL(constant, zend_strndup(value, value_length), value_length, 0);
3277 : } else {
3278 0 : ALLOC_ZVAL(constant);
3279 0 : ZVAL_STRINGL(constant, value, value_length, 1);
3280 : }
3281 335027 : INIT_PZVAL(constant);
3282 335027 : return zend_declare_class_constant(ce, name, name_length, constant TSRMLS_CC);
3283 : }
3284 : /* }}} */
3285 :
3286 : ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value TSRMLS_DC) /* {{{ */
3287 123431 : {
3288 123431 : return zend_declare_class_constant_stringl(ce, name, name_length, value, strlen(value) TSRMLS_CC);
3289 : }
3290 : /* }}} */
3291 :
3292 : ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char *name, int name_length, zval *value TSRMLS_DC) /* {{{ */
3293 6864 : {
3294 : zval *property;
3295 6864 : zend_class_entry *old_scope = EG(scope);
3296 :
3297 6864 : EG(scope) = scope;
3298 :
3299 6864 : if (!Z_OBJ_HT_P(object)->write_property) {
3300 : char *class_name;
3301 : zend_uint class_name_len;
3302 :
3303 0 : zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC);
3304 :
3305 0 : zend_error(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, class_name);
3306 : }
3307 6864 : MAKE_STD_ZVAL(property);
3308 6864 : ZVAL_STRINGL(property, name, name_length, 1);
3309 6864 : Z_OBJ_HT_P(object)->write_property(object, property, value TSRMLS_CC);
3310 6858 : zval_ptr_dtor(&property);
3311 :
3312 6858 : EG(scope) = old_scope;
3313 6858 : }
3314 : /* }}} */
3315 :
3316 : ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, char *name, int name_length TSRMLS_DC) /* {{{ */
3317 0 : {
3318 : zval *tmp;
3319 :
3320 0 : ALLOC_ZVAL(tmp);
3321 0 : Z_UNSET_ISREF_P(tmp);
3322 0 : Z_SET_REFCOUNT_P(tmp, 0);
3323 0 : ZVAL_NULL(tmp);
3324 0 : zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
3325 0 : }
3326 : /* }}} */
3327 :
3328 : ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC) /* {{{ */
3329 0 : {
3330 : zval *tmp;
3331 :
3332 0 : ALLOC_ZVAL(tmp);
3333 0 : Z_UNSET_ISREF_P(tmp);
3334 0 : Z_SET_REFCOUNT_P(tmp, 0);
3335 0 : ZVAL_BOOL(tmp, value);
3336 0 : zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
3337 0 : }
3338 : /* }}} */
3339 :
3340 : ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC) /* {{{ */
3341 1684 : {
3342 : zval *tmp;
3343 :
3344 1684 : ALLOC_ZVAL(tmp);
3345 1684 : Z_UNSET_ISREF_P(tmp);
3346 1684 : Z_SET_REFCOUNT_P(tmp, 0);
3347 1684 : ZVAL_LONG(tmp, value);
3348 1684 : zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
3349 1684 : }
3350 : /* }}} */
3351 :
3352 : ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, char *name, int name_length, double value TSRMLS_DC) /* {{{ */
3353 0 : {
3354 : zval *tmp;
3355 :
3356 0 : ALLOC_ZVAL(tmp);
3357 0 : Z_UNSET_ISREF_P(tmp);
3358 0 : Z_SET_REFCOUNT_P(tmp, 0);
3359 0 : ZVAL_DOUBLE(tmp, value);
3360 0 : zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
3361 0 : }
3362 : /* }}} */
3363 :
3364 : ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, char *name, int name_length, const char *value TSRMLS_DC) /* {{{ */
3365 3052 : {
3366 : zval *tmp;
3367 :
3368 3052 : ALLOC_ZVAL(tmp);
3369 3052 : Z_UNSET_ISREF_P(tmp);
3370 3052 : Z_SET_REFCOUNT_P(tmp, 0);
3371 3052 : ZVAL_STRING(tmp, value, 1);
3372 3052 : zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
3373 3052 : }
3374 : /* }}} */
3375 :
3376 : ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, char *name, int name_length, const char *value, int value_len TSRMLS_DC) /* {{{ */
3377 0 : {
3378 : zval *tmp;
3379 :
3380 0 : ALLOC_ZVAL(tmp);
3381 0 : Z_UNSET_ISREF_P(tmp);
3382 0 : Z_SET_REFCOUNT_P(tmp, 0);
3383 0 : ZVAL_STRINGL(tmp, value, value_len, 1);
3384 0 : zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
3385 0 : }
3386 : /* }}} */
3387 :
3388 : ZEND_API int zend_update_static_property(zend_class_entry *scope, char *name, int name_length, zval *value TSRMLS_DC) /* {{{ */
3389 0 : {
3390 : zval **property;
3391 0 : zend_class_entry *old_scope = EG(scope);
3392 :
3393 0 : EG(scope) = scope;
3394 0 : property = zend_std_get_static_property(scope, name, name_length, 0 TSRMLS_CC);
3395 0 : EG(scope) = old_scope;
3396 0 : if (!property) {
3397 0 : return FAILURE;
3398 : } else {
3399 0 : if (*property != value) {
3400 0 : if (PZVAL_IS_REF(*property)) {
3401 0 : zval_dtor(*property);
3402 0 : Z_TYPE_PP(property) = Z_TYPE_P(value);
3403 0 : (*property)->value = value->value;
3404 0 : if (Z_REFCOUNT_P(value) > 0) {
3405 0 : zval_copy_ctor(*property);
3406 : }
3407 : } else {
3408 0 : zval *garbage = *property;
3409 :
3410 0 : Z_ADDREF_P(value);
3411 0 : if (PZVAL_IS_REF(value)) {
3412 0 : SEPARATE_ZVAL(&value);
3413 : }
3414 0 : *property = value;
3415 0 : zval_ptr_dtor(&garbage);
3416 : }
3417 : }
3418 0 : return SUCCESS;
3419 : }
3420 : }
3421 : /* }}} */
3422 :
3423 : ZEND_API int zend_update_static_property_null(zend_class_entry *scope, char *name, int name_length TSRMLS_DC) /* {{{ */
3424 0 : {
3425 : zval *tmp;
3426 :
3427 0 : ALLOC_ZVAL(tmp);
3428 0 : Z_UNSET_ISREF_P(tmp);
3429 0 : Z_SET_REFCOUNT_P(tmp, 0);
3430 0 : ZVAL_NULL(tmp);
3431 0 : return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
3432 : }
3433 : /* }}} */
3434 :
3435 : ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC) /* {{{ */
3436 0 : {
3437 : zval *tmp;
3438 :
3439 0 : ALLOC_ZVAL(tmp);
3440 0 : Z_UNSET_ISREF_P(tmp);
3441 0 : Z_SET_REFCOUNT_P(tmp, 0);
3442 0 : ZVAL_BOOL(tmp, value);
3443 0 : return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
3444 : }
3445 : /* }}} */
3446 :
3447 : ZEND_API int zend_update_static_property_long(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC) /* {{{ */
3448 0 : {
3449 : zval *tmp;
3450 :
3451 0 : ALLOC_ZVAL(tmp);
3452 0 : Z_UNSET_ISREF_P(tmp);
3453 0 : Z_SET_REFCOUNT_P(tmp, 0);
3454 0 : ZVAL_LONG(tmp, value);
3455 0 : return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
3456 : }
3457 : /* }}} */
3458 :
3459 : ZEND_API int zend_update_static_property_double(zend_class_entry *scope, char *name, int name_length, double value TSRMLS_DC) /* {{{ */
3460 0 : {
3461 : zval *tmp;
3462 :
3463 0 : ALLOC_ZVAL(tmp);
3464 0 : Z_UNSET_ISREF_P(tmp);
3465 0 : Z_SET_REFCOUNT_P(tmp, 0);
3466 0 : ZVAL_DOUBLE(tmp, value);
3467 0 : return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
3468 : }
3469 : /* }}} */
3470 :
3471 : ZEND_API int zend_update_static_property_string(zend_class_entry *scope, char *name, int name_length, const char *value TSRMLS_DC) /* {{{ */
3472 0 : {
3473 : zval *tmp;
3474 :
3475 0 : ALLOC_ZVAL(tmp);
3476 0 : Z_UNSET_ISREF_P(tmp);
3477 0 : Z_SET_REFCOUNT_P(tmp, 0);
3478 0 : ZVAL_STRING(tmp, value, 1);
3479 0 : return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
3480 : }
3481 : /* }}} */
3482 :
3483 : ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, char *name, int name_length, const char *value, int value_len TSRMLS_DC) /* {{{ */
3484 0 : {
3485 : zval *tmp;
3486 :
3487 0 : ALLOC_ZVAL(tmp);
3488 0 : Z_UNSET_ISREF_P(tmp);
3489 0 : Z_SET_REFCOUNT_P(tmp, 0);
3490 0 : ZVAL_STRINGL(tmp, value, value_len, 1);
3491 0 : return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
3492 : }
3493 : /* }}} */
3494 :
3495 : ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *name, int name_length, zend_bool silent TSRMLS_DC) /* {{{ */
3496 1507 : {
3497 : zval *property, *value;
3498 1507 : zend_class_entry *old_scope = EG(scope);
3499 :
3500 1507 : EG(scope) = scope;
3501 :
3502 1507 : if (!Z_OBJ_HT_P(object)->read_property) {
3503 : char *class_name;
3504 : zend_uint class_name_len;
3505 :
3506 0 : zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC);
3507 0 : zend_error(E_CORE_ERROR, "Property %s of class %s cannot be read", name, class_name);
3508 : }
3509 :
3510 1507 : MAKE_STD_ZVAL(property);
3511 1507 : ZVAL_STRINGL(property, name, name_length, 1);
3512 1507 : value = Z_OBJ_HT_P(object)->read_property(object, property, silent?BP_VAR_IS:BP_VAR_R TSRMLS_CC);
3513 1507 : zval_ptr_dtor(&property);
3514 :
3515 1507 : EG(scope) = old_scope;
3516 1507 : return value;
3517 : }
3518 : /* }}} */
3519 :
3520 : ZEND_API zval *zend_read_static_property(zend_class_entry *scope, char *name, int name_length, zend_bool silent TSRMLS_DC) /* {{{ */
3521 0 : {
3522 : zval **property;
3523 0 : zend_class_entry *old_scope = EG(scope);
3524 :
3525 0 : EG(scope) = scope;
3526 0 : property = zend_std_get_static_property(scope, name, name_length, silent TSRMLS_CC);
3527 0 : EG(scope) = old_scope;
3528 :
3529 0 : return property?*property:NULL;
3530 : }
3531 : /* }}} */
3532 :
3533 : ZEND_API void zend_save_error_handling(zend_error_handling *current TSRMLS_DC) /* {{{ */
3534 9539 : {
3535 9539 : current->handling = EG(error_handling);
3536 9539 : current->exception = EG(exception_class);
3537 9539 : current->user_handler = EG(user_error_handler);
3538 9539 : if (current->user_handler) {
3539 10 : Z_ADDREF_P(current->user_handler);
3540 : }
3541 9539 : }
3542 : /* }}} */
3543 :
3544 : ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current TSRMLS_DC) /* {{{ */
3545 9539 : {
3546 9539 : if (current) {
3547 9539 : zend_save_error_handling(current TSRMLS_CC);
3548 9539 : if (error_handling != EH_NORMAL && EG(user_error_handler)) {
3549 10 : zval_ptr_dtor(&EG(user_error_handler));
3550 10 : EG(user_error_handler) = NULL;
3551 : }
3552 : }
3553 9539 : EG(error_handling) = error_handling;
3554 9539 : EG(exception_class) = error_handling == EH_THROW ? exception_class : NULL;
3555 9539 : }
3556 : /* }}} */
3557 :
3558 : ZEND_API void zend_restore_error_handling(zend_error_handling *saved TSRMLS_DC) /* {{{ */
3559 9539 : {
3560 9539 : EG(error_handling) = saved->handling;
3561 9539 : EG(exception_class) = saved->handling == EH_THROW ? saved->exception : NULL;
3562 9549 : if (saved->user_handler && saved->user_handler != EG(user_error_handler)) {
3563 10 : if (EG(user_error_handler)) {
3564 0 : zval_ptr_dtor(&EG(user_error_handler));
3565 : }
3566 10 : EG(user_error_handler) = saved->user_handler;
3567 9529 : } else if (saved->user_handler) {
3568 0 : zval_ptr_dtor(&saved->user_handler);
3569 : }
3570 9539 : saved->user_handler = NULL;
3571 9539 : }
3572 : /* }}} */
3573 :
3574 : /*
3575 : * Local variables:
3576 : * tab-width: 4
3577 : * c-basic-offset: 4
3578 : * indent-tabs-mode: t
3579 : * End:
3580 : */
|