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