This source file includes following definitions.
- var_push
- var_push_dtor
- var_push_dtor_no_addref
- var_replace
- var_access
- var_destroy
- unserialize_str
- parse_iv2
- parse_iv
- parse_uiv
- process_nested_data
- finish_nested_data
- object_custom
- object_common1
- object_common2
- php_var_unserialize
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include "php.h"
23 #include "ext/standard/php_var.h"
24 #include "php_incomplete_class.h"
25
26
27 #define VAR_ENTRIES_MAX 1024
28 #define VAR_ENTRIES_DBG 0
29
30 typedef struct {
31 zval *data[VAR_ENTRIES_MAX];
32 long used_slots;
33 void *next;
34 } var_entries;
35
36 static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval)
37 {
38 var_entries *var_hash = (*var_hashx)->last;
39 #if VAR_ENTRIES_DBG
40 fprintf(stderr, "var_push(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval));
41 #endif
42
43 if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) {
44 var_hash = emalloc(sizeof(var_entries));
45 var_hash->used_slots = 0;
46 var_hash->next = 0;
47
48 if (!(*var_hashx)->first) {
49 (*var_hashx)->first = var_hash;
50 } else {
51 ((var_entries *) (*var_hashx)->last)->next = var_hash;
52 }
53
54 (*var_hashx)->last = var_hash;
55 }
56
57 var_hash->data[var_hash->used_slots++] = *rval;
58 }
59
60 PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
61 {
62 var_entries *var_hash;
63
64 if (!var_hashx || !*var_hashx) {
65 return;
66 }
67
68 var_hash = (*var_hashx)->last_dtor;
69 #if VAR_ENTRIES_DBG
70 fprintf(stderr, "var_push_dtor(%p, %ld): %d\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval));
71 #endif
72
73 if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) {
74 var_hash = emalloc(sizeof(var_entries));
75 var_hash->used_slots = 0;
76 var_hash->next = 0;
77
78 if (!(*var_hashx)->first_dtor) {
79 (*var_hashx)->first_dtor = var_hash;
80 } else {
81 ((var_entries *) (*var_hashx)->last_dtor)->next = var_hash;
82 }
83
84 (*var_hashx)->last_dtor = var_hash;
85 }
86
87 Z_ADDREF_PP(rval);
88 var_hash->data[var_hash->used_slots++] = *rval;
89 }
90
91 PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval)
92 {
93 var_entries *var_hash;
94
95 if (!var_hashx || !*var_hashx) {
96 return;
97 }
98
99 var_hash = (*var_hashx)->last_dtor;
100 #if VAR_ENTRIES_DBG
101 fprintf(stderr, "var_push_dtor_no_addref(%p, %ld): %d (%d)\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval));
102 #endif
103
104 if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) {
105 var_hash = emalloc(sizeof(var_entries));
106 var_hash->used_slots = 0;
107 var_hash->next = 0;
108
109 if (!(*var_hashx)->first_dtor) {
110 (*var_hashx)->first_dtor = var_hash;
111 } else {
112 ((var_entries *) (*var_hashx)->last_dtor)->next = var_hash;
113 }
114
115 (*var_hashx)->last_dtor = var_hash;
116 }
117
118 var_hash->data[var_hash->used_slots++] = *rval;
119 }
120
121 PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval)
122 {
123 long i;
124 var_entries *var_hash = (*var_hashx)->first;
125 #if VAR_ENTRIES_DBG
126 fprintf(stderr, "var_replace(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(nzval));
127 #endif
128
129 while (var_hash) {
130 for (i = 0; i < var_hash->used_slots; i++) {
131 if (var_hash->data[i] == ozval) {
132 var_hash->data[i] = *nzval;
133
134 }
135 }
136 var_hash = var_hash->next;
137 }
138 }
139
140 static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store)
141 {
142 var_entries *var_hash = (*var_hashx)->first;
143 #if VAR_ENTRIES_DBG
144 fprintf(stderr, "var_access(%ld): %ld\n", var_hash?var_hash->used_slots:-1L, id);
145 #endif
146
147 while (id >= VAR_ENTRIES_MAX && var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
148 var_hash = var_hash->next;
149 id -= VAR_ENTRIES_MAX;
150 }
151
152 if (!var_hash) return !SUCCESS;
153
154 if (id < 0 || id >= var_hash->used_slots) return !SUCCESS;
155
156 *store = &var_hash->data[id];
157
158 return SUCCESS;
159 }
160
161 PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
162 {
163 void *next;
164 long i;
165 var_entries *var_hash = (*var_hashx)->first;
166 #if VAR_ENTRIES_DBG
167 fprintf(stderr, "var_destroy(%ld)\n", var_hash?var_hash->used_slots:-1L);
168 #endif
169
170 while (var_hash) {
171 next = var_hash->next;
172 efree(var_hash);
173 var_hash = next;
174 }
175
176 var_hash = (*var_hashx)->first_dtor;
177
178 while (var_hash) {
179 for (i = 0; i < var_hash->used_slots; i++) {
180 #if VAR_ENTRIES_DBG
181 fprintf(stderr, "var_destroy dtor(%p, %ld)\n", var_hash->data[i], Z_REFCOUNT_P(var_hash->data[i]));
182 #endif
183 zval_ptr_dtor(&var_hash->data[i]);
184 }
185 next = var_hash->next;
186 efree(var_hash);
187 var_hash = next;
188 }
189 }
190
191
192
193 static char *unserialize_str(const unsigned char **p, size_t *len, size_t maxlen)
194 {
195 size_t i, j;
196 char *str = safe_emalloc(*len, 1, 1);
197 unsigned char *end = *(unsigned char **)p+maxlen;
198
199 if (end < *p) {
200 efree(str);
201 return NULL;
202 }
203
204 for (i = 0; i < *len; i++) {
205 if (*p >= end) {
206 efree(str);
207 return NULL;
208 }
209 if (**p != '\\') {
210 str[i] = (char)**p;
211 } else {
212 unsigned char ch = 0;
213
214 for (j = 0; j < 2; j++) {
215 (*p)++;
216 if (**p >= '0' && **p <= '9') {
217 ch = (ch << 4) + (**p -'0');
218 } else if (**p >= 'a' && **p <= 'f') {
219 ch = (ch << 4) + (**p -'a'+10);
220 } else if (**p >= 'A' && **p <= 'F') {
221 ch = (ch << 4) + (**p -'A'+10);
222 } else {
223 efree(str);
224 return NULL;
225 }
226 }
227 str[i] = (char)ch;
228 }
229 (*p)++;
230 }
231 str[i] = 0;
232 *len = i;
233 return str;
234 }
235
236 #define YYFILL(n) do { } while (0)
237 #define YYCTYPE unsigned char
238 #define YYCURSOR cursor
239 #define YYLIMIT limit
240 #define YYMARKER marker
241
242
243
244
245
246
247 static inline long parse_iv2(const unsigned char *p, const unsigned char **q)
248 {
249 char cursor;
250 long result = 0;
251 int neg = 0;
252
253 switch (*p) {
254 case '-':
255 neg++;
256
257 case '+':
258 p++;
259 }
260
261 while (1) {
262 cursor = (char)*p;
263 if (cursor >= '0' && cursor <= '9') {
264 result = result * 10 + (size_t)(cursor - (unsigned char)'0');
265 } else {
266 break;
267 }
268 p++;
269 }
270 if (q) *q = p;
271 if (neg) return -result;
272 return result;
273 }
274
275 static inline long parse_iv(const unsigned char *p)
276 {
277 return parse_iv2(p, NULL);
278 }
279
280
281 static inline size_t parse_uiv(const unsigned char *p)
282 {
283 unsigned char cursor;
284 size_t result = 0;
285
286 if (*p == '+') {
287 p++;
288 }
289
290 while (1) {
291 cursor = *p;
292 if (cursor >= '0' && cursor <= '9') {
293 result = result * 10 + (size_t)(cursor - (unsigned char)'0');
294 } else {
295 break;
296 }
297 p++;
298 }
299 return result;
300 }
301
302 #define UNSERIALIZE_PARAMETER zval **rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC
303 #define UNSERIALIZE_PASSTHRU rval, p, max, var_hash TSRMLS_CC
304
305 static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long elements, int objprops)
306 {
307 while (elements-- > 0) {
308 zval *key, *data, **old_data;
309
310 ALLOC_INIT_ZVAL(key);
311
312 if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) {
313 var_push_dtor_no_addref(var_hash, &key);
314 return 0;
315 }
316
317 if (Z_TYPE_P(key) != IS_LONG && Z_TYPE_P(key) != IS_STRING) {
318 var_push_dtor_no_addref(var_hash, &key);
319 return 0;
320 }
321
322 ALLOC_INIT_ZVAL(data);
323
324 if (!php_var_unserialize(&data, p, max, var_hash TSRMLS_CC)) {
325 var_push_dtor_no_addref(var_hash, &key);
326 var_push_dtor_no_addref(var_hash, &data);
327 return 0;
328 }
329
330 if (!objprops) {
331 switch (Z_TYPE_P(key)) {
332 case IS_LONG:
333 if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)==SUCCESS) {
334 var_push_dtor(var_hash, old_data);
335 }
336 zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL);
337 break;
338 case IS_STRING:
339 if (zend_symtable_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
340 var_push_dtor(var_hash, old_data);
341 }
342 zend_symtable_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
343 break;
344 }
345 } else {
346
347 convert_to_string(key);
348 if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
349 var_push_dtor(var_hash, old_data);
350 }
351 zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data,
352 sizeof data, NULL);
353 }
354 var_push_dtor(var_hash, &data);
355 var_push_dtor_no_addref(var_hash, &key);
356
357 if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
358 (*p)--;
359 return 0;
360 }
361 }
362
363 return 1;
364 }
365
366 static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
367 {
368 if (*((*p)++) == '}')
369 return 1;
370
371 #if SOMETHING_NEW_MIGHT_LEAD_TO_CRASH_ENABLE_IF_YOU_ARE_BRAVE
372 zval_ptr_dtor(rval);
373 #endif
374 return 0;
375 }
376
377 static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
378 {
379 long datalen;
380
381 datalen = parse_iv2((*p) + 2, p);
382
383 (*p) += 2;
384
385 if (datalen < 0 || (max - (*p)) <= datalen) {
386 zend_error(E_WARNING, "Insufficient data for unserializing - %ld required, %ld present", datalen, (long)(max - (*p)));
387 return 0;
388 }
389
390 if (ce->unserialize == NULL) {
391 zend_error(E_WARNING, "Class %s has no unserializer", ce->name);
392 object_init_ex(*rval, ce);
393 } else if (ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) {
394 return 0;
395 }
396
397 (*p) += datalen;
398
399 return finish_nested_data(UNSERIALIZE_PASSTHRU);
400 }
401
402 static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
403 {
404 long elements;
405
406 elements = parse_iv2((*p) + 2, p);
407
408 (*p) += 2;
409
410 if (ce->serialize == NULL) {
411 object_init_ex(*rval, ce);
412 } else {
413
414
415 zend_error(E_WARNING, "Erroneous data format for unserializing '%s'", ce->name);
416 return 0;
417 }
418
419 return elements;
420 }
421
422 #ifdef PHP_WIN32
423 # pragma optimize("", off)
424 #endif
425 static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
426 {
427 zval *retval_ptr = NULL;
428 zval fname;
429
430 if (Z_TYPE_PP(rval) != IS_OBJECT) {
431 return 0;
432 }
433
434 if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements, 1)) {
435 return 0;
436 }
437
438 if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
439 zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) {
440 INIT_PZVAL(&fname);
441 ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0);
442 BG(serialize_lock)++;
443 call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
444 BG(serialize_lock)--;
445 }
446
447 if (retval_ptr) {
448 zval_ptr_dtor(&retval_ptr);
449 }
450
451 if (EG(exception)) {
452 return 0;
453 }
454
455 return finish_nested_data(UNSERIALIZE_PASSTHRU);
456
457 }
458 #ifdef PHP_WIN32
459 # pragma optimize("", on)
460 #endif
461
462 PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
463 {
464 const unsigned char *cursor, *limit, *marker, *start;
465 zval **rval_ref;
466
467 limit = max;
468 cursor = *p;
469
470 if (YYCURSOR >= YYLIMIT) {
471 return 0;
472 }
473
474 if (var_hash && cursor[0] != 'R') {
475 var_push(var_hash, rval);
476 }
477
478 start = cursor;
479
480
481
482
483 {
484 YYCTYPE yych;
485 static const unsigned char yybm[] = {
486 0, 0, 0, 0, 0, 0, 0, 0,
487 0, 0, 0, 0, 0, 0, 0, 0,
488 0, 0, 0, 0, 0, 0, 0, 0,
489 0, 0, 0, 0, 0, 0, 0, 0,
490 0, 0, 0, 0, 0, 0, 0, 0,
491 0, 0, 0, 0, 0, 0, 0, 0,
492 128, 128, 128, 128, 128, 128, 128, 128,
493 128, 128, 0, 0, 0, 0, 0, 0,
494 0, 0, 0, 0, 0, 0, 0, 0,
495 0, 0, 0, 0, 0, 0, 0, 0,
496 0, 0, 0, 0, 0, 0, 0, 0,
497 0, 0, 0, 0, 0, 0, 0, 0,
498 0, 0, 0, 0, 0, 0, 0, 0,
499 0, 0, 0, 0, 0, 0, 0, 0,
500 0, 0, 0, 0, 0, 0, 0, 0,
501 0, 0, 0, 0, 0, 0, 0, 0,
502 0, 0, 0, 0, 0, 0, 0, 0,
503 0, 0, 0, 0, 0, 0, 0, 0,
504 0, 0, 0, 0, 0, 0, 0, 0,
505 0, 0, 0, 0, 0, 0, 0, 0,
506 0, 0, 0, 0, 0, 0, 0, 0,
507 0, 0, 0, 0, 0, 0, 0, 0,
508 0, 0, 0, 0, 0, 0, 0, 0,
509 0, 0, 0, 0, 0, 0, 0, 0,
510 0, 0, 0, 0, 0, 0, 0, 0,
511 0, 0, 0, 0, 0, 0, 0, 0,
512 0, 0, 0, 0, 0, 0, 0, 0,
513 0, 0, 0, 0, 0, 0, 0, 0,
514 0, 0, 0, 0, 0, 0, 0, 0,
515 0, 0, 0, 0, 0, 0, 0, 0,
516 0, 0, 0, 0, 0, 0, 0, 0,
517 0, 0, 0, 0, 0, 0, 0, 0,
518 };
519
520 if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
521 yych = *YYCURSOR;
522 switch (yych) {
523 case 'C':
524 case 'O': goto yy13;
525 case 'N': goto yy5;
526 case 'R': goto yy2;
527 case 'S': goto yy10;
528 case 'a': goto yy11;
529 case 'b': goto yy6;
530 case 'd': goto yy8;
531 case 'i': goto yy7;
532 case 'o': goto yy12;
533 case 'r': goto yy4;
534 case 's': goto yy9;
535 case '}': goto yy14;
536 default: goto yy16;
537 }
538 yy2:
539 yych = *(YYMARKER = ++YYCURSOR);
540 if (yych == ':') goto yy95;
541 yy3:
542 { return 0; }
543 yy4:
544 yych = *(YYMARKER = ++YYCURSOR);
545 if (yych == ':') goto yy89;
546 goto yy3;
547 yy5:
548 yych = *++YYCURSOR;
549 if (yych == ';') goto yy87;
550 goto yy3;
551 yy6:
552 yych = *(YYMARKER = ++YYCURSOR);
553 if (yych == ':') goto yy83;
554 goto yy3;
555 yy7:
556 yych = *(YYMARKER = ++YYCURSOR);
557 if (yych == ':') goto yy77;
558 goto yy3;
559 yy8:
560 yych = *(YYMARKER = ++YYCURSOR);
561 if (yych == ':') goto yy53;
562 goto yy3;
563 yy9:
564 yych = *(YYMARKER = ++YYCURSOR);
565 if (yych == ':') goto yy46;
566 goto yy3;
567 yy10:
568 yych = *(YYMARKER = ++YYCURSOR);
569 if (yych == ':') goto yy39;
570 goto yy3;
571 yy11:
572 yych = *(YYMARKER = ++YYCURSOR);
573 if (yych == ':') goto yy32;
574 goto yy3;
575 yy12:
576 yych = *(YYMARKER = ++YYCURSOR);
577 if (yych == ':') goto yy25;
578 goto yy3;
579 yy13:
580 yych = *(YYMARKER = ++YYCURSOR);
581 if (yych == ':') goto yy17;
582 goto yy3;
583 yy14:
584 ++YYCURSOR;
585 {
586
587 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
588 return 0;
589 }
590 yy16:
591 yych = *++YYCURSOR;
592 goto yy3;
593 yy17:
594 yych = *++YYCURSOR;
595 if (yybm[0+yych] & 128) {
596 goto yy20;
597 }
598 if (yych == '+') goto yy19;
599 yy18:
600 YYCURSOR = YYMARKER;
601 goto yy3;
602 yy19:
603 yych = *++YYCURSOR;
604 if (yybm[0+yych] & 128) {
605 goto yy20;
606 }
607 goto yy18;
608 yy20:
609 ++YYCURSOR;
610 if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
611 yych = *YYCURSOR;
612 if (yybm[0+yych] & 128) {
613 goto yy20;
614 }
615 if (yych <= '/') goto yy18;
616 if (yych >= ';') goto yy18;
617 yych = *++YYCURSOR;
618 if (yych != '"') goto yy18;
619 ++YYCURSOR;
620 {
621 size_t len, len2, len3, maxlen;
622 long elements;
623 char *class_name;
624 zend_class_entry *ce;
625 zend_class_entry **pce;
626 int incomplete_class = 0;
627
628 int custom_object = 0;
629
630 zval *user_func;
631 zval *retval_ptr;
632 zval **args[1];
633 zval *arg_func_name;
634
635 if (!var_hash) return 0;
636 if (*start == 'C') {
637 custom_object = 1;
638 }
639
640 INIT_PZVAL(*rval);
641 len2 = len = parse_uiv(start + 2);
642 maxlen = max - YYCURSOR;
643 if (maxlen < len || len == 0) {
644 *p = start + 2;
645 return 0;
646 }
647
648 class_name = (char*)YYCURSOR;
649
650 YYCURSOR += len;
651
652 if (*(YYCURSOR) != '"') {
653 *p = YYCURSOR;
654 return 0;
655 }
656 if (*(YYCURSOR+1) != ':') {
657 *p = YYCURSOR+1;
658 return 0;
659 }
660
661 len3 = strspn(class_name, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\");
662 if (len3 != len)
663 {
664 *p = YYCURSOR + len3 - len;
665 return 0;
666 }
667
668 class_name = estrndup(class_name, len);
669
670 do {
671
672 BG(serialize_lock)++;
673 if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
674 BG(serialize_lock)--;
675 if (EG(exception)) {
676 efree(class_name);
677 return 0;
678 }
679 ce = *pce;
680 break;
681 }
682 BG(serialize_lock)--;
683
684 if (EG(exception)) {
685 efree(class_name);
686 return 0;
687 }
688
689
690 if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
691 incomplete_class = 1;
692 ce = PHP_IC_ENTRY;
693 break;
694 }
695
696
697 MAKE_STD_ZVAL(user_func);
698 ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
699 args[0] = &arg_func_name;
700 MAKE_STD_ZVAL(arg_func_name);
701 ZVAL_STRING(arg_func_name, class_name, 1);
702 BG(serialize_lock)++;
703 if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
704 BG(serialize_lock)--;
705 if (EG(exception)) {
706 efree(class_name);
707 zval_ptr_dtor(&user_func);
708 zval_ptr_dtor(&arg_func_name);
709 return 0;
710 }
711 php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
712 incomplete_class = 1;
713 ce = PHP_IC_ENTRY;
714 zval_ptr_dtor(&user_func);
715 zval_ptr_dtor(&arg_func_name);
716 break;
717 }
718 BG(serialize_lock)--;
719 if (retval_ptr) {
720 zval_ptr_dtor(&retval_ptr);
721 }
722 if (EG(exception)) {
723 efree(class_name);
724 zval_ptr_dtor(&user_func);
725 zval_ptr_dtor(&arg_func_name);
726 return 0;
727 }
728
729
730 if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
731 ce = *pce;
732 } else {
733 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val);
734 incomplete_class = 1;
735 ce = PHP_IC_ENTRY;
736 }
737
738 zval_ptr_dtor(&user_func);
739 zval_ptr_dtor(&arg_func_name);
740 break;
741 } while (1);
742
743 *p = YYCURSOR;
744
745 if (custom_object) {
746 int ret;
747
748 ret = object_custom(UNSERIALIZE_PASSTHRU, ce);
749
750 if (ret && incomplete_class) {
751 php_store_class_name(*rval, class_name, len2);
752 }
753 efree(class_name);
754 return ret;
755 }
756
757 elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
758
759 if (incomplete_class) {
760 php_store_class_name(*rval, class_name, len2);
761 }
762 efree(class_name);
763
764 return object_common2(UNSERIALIZE_PASSTHRU, elements);
765 }
766 yy25:
767 yych = *++YYCURSOR;
768 if (yych <= ',') {
769 if (yych != '+') goto yy18;
770 } else {
771 if (yych <= '-') goto yy26;
772 if (yych <= '/') goto yy18;
773 if (yych <= '9') goto yy27;
774 goto yy18;
775 }
776 yy26:
777 yych = *++YYCURSOR;
778 if (yych <= '/') goto yy18;
779 if (yych >= ':') goto yy18;
780 yy27:
781 ++YYCURSOR;
782 if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
783 yych = *YYCURSOR;
784 if (yych <= '/') goto yy18;
785 if (yych <= '9') goto yy27;
786 if (yych >= ';') goto yy18;
787 yych = *++YYCURSOR;
788 if (yych != '"') goto yy18;
789 ++YYCURSOR;
790 {
791 if (!var_hash) return 0;
792
793 INIT_PZVAL(*rval);
794
795 return object_common2(UNSERIALIZE_PASSTHRU,
796 object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
797 }
798 yy32:
799 yych = *++YYCURSOR;
800 if (yych == '+') goto yy33;
801 if (yych <= '/') goto yy18;
802 if (yych <= '9') goto yy34;
803 goto yy18;
804 yy33:
805 yych = *++YYCURSOR;
806 if (yych <= '/') goto yy18;
807 if (yych >= ':') goto yy18;
808 yy34:
809 ++YYCURSOR;
810 if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
811 yych = *YYCURSOR;
812 if (yych <= '/') goto yy18;
813 if (yych <= '9') goto yy34;
814 if (yych >= ';') goto yy18;
815 yych = *++YYCURSOR;
816 if (yych != '{') goto yy18;
817 ++YYCURSOR;
818 {
819 long elements = parse_iv(start + 2);
820
821 *p = YYCURSOR;
822 if (!var_hash) return 0;
823
824 if (elements < 0) {
825 return 0;
826 }
827
828 INIT_PZVAL(*rval);
829
830 array_init_size(*rval, elements);
831
832 if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) {
833 return 0;
834 }
835
836 return finish_nested_data(UNSERIALIZE_PASSTHRU);
837 }
838 yy39:
839 yych = *++YYCURSOR;
840 if (yych == '+') goto yy40;
841 if (yych <= '/') goto yy18;
842 if (yych <= '9') goto yy41;
843 goto yy18;
844 yy40:
845 yych = *++YYCURSOR;
846 if (yych <= '/') goto yy18;
847 if (yych >= ':') goto yy18;
848 yy41:
849 ++YYCURSOR;
850 if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
851 yych = *YYCURSOR;
852 if (yych <= '/') goto yy18;
853 if (yych <= '9') goto yy41;
854 if (yych >= ';') goto yy18;
855 yych = *++YYCURSOR;
856 if (yych != '"') goto yy18;
857 ++YYCURSOR;
858 {
859 size_t len, maxlen;
860 char *str;
861
862 len = parse_uiv(start + 2);
863 maxlen = max - YYCURSOR;
864 if (maxlen < len) {
865 *p = start + 2;
866 return 0;
867 }
868
869 if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) {
870 return 0;
871 }
872
873 if (*(YYCURSOR) != '"') {
874 efree(str);
875 *p = YYCURSOR;
876 return 0;
877 }
878
879 YYCURSOR += 2;
880 *p = YYCURSOR;
881
882 INIT_PZVAL(*rval);
883 ZVAL_STRINGL(*rval, str, len, 0);
884 return 1;
885 }
886 yy46:
887 yych = *++YYCURSOR;
888 if (yych == '+') goto yy47;
889 if (yych <= '/') goto yy18;
890 if (yych <= '9') goto yy48;
891 goto yy18;
892 yy47:
893 yych = *++YYCURSOR;
894 if (yych <= '/') goto yy18;
895 if (yych >= ':') goto yy18;
896 yy48:
897 ++YYCURSOR;
898 if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
899 yych = *YYCURSOR;
900 if (yych <= '/') goto yy18;
901 if (yych <= '9') goto yy48;
902 if (yych >= ';') goto yy18;
903 yych = *++YYCURSOR;
904 if (yych != '"') goto yy18;
905 ++YYCURSOR;
906 {
907 size_t len, maxlen;
908 char *str;
909
910 len = parse_uiv(start + 2);
911 maxlen = max - YYCURSOR;
912 if (maxlen < len) {
913 *p = start + 2;
914 return 0;
915 }
916
917 str = (char*)YYCURSOR;
918
919 YYCURSOR += len;
920
921 if (*(YYCURSOR) != '"') {
922 *p = YYCURSOR;
923 return 0;
924 }
925
926 YYCURSOR += 2;
927 *p = YYCURSOR;
928
929 INIT_PZVAL(*rval);
930 ZVAL_STRINGL(*rval, str, len, 1);
931 return 1;
932 }
933 yy53:
934 yych = *++YYCURSOR;
935 if (yych <= '/') {
936 if (yych <= ',') {
937 if (yych == '+') goto yy57;
938 goto yy18;
939 } else {
940 if (yych <= '-') goto yy55;
941 if (yych <= '.') goto yy60;
942 goto yy18;
943 }
944 } else {
945 if (yych <= 'I') {
946 if (yych <= '9') goto yy58;
947 if (yych <= 'H') goto yy18;
948 goto yy56;
949 } else {
950 if (yych != 'N') goto yy18;
951 }
952 }
953 yych = *++YYCURSOR;
954 if (yych == 'A') goto yy76;
955 goto yy18;
956 yy55:
957 yych = *++YYCURSOR;
958 if (yych <= '/') {
959 if (yych == '.') goto yy60;
960 goto yy18;
961 } else {
962 if (yych <= '9') goto yy58;
963 if (yych != 'I') goto yy18;
964 }
965 yy56:
966 yych = *++YYCURSOR;
967 if (yych == 'N') goto yy72;
968 goto yy18;
969 yy57:
970 yych = *++YYCURSOR;
971 if (yych == '.') goto yy60;
972 if (yych <= '/') goto yy18;
973 if (yych >= ':') goto yy18;
974 yy58:
975 ++YYCURSOR;
976 if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
977 yych = *YYCURSOR;
978 if (yych <= ':') {
979 if (yych <= '.') {
980 if (yych <= '-') goto yy18;
981 goto yy70;
982 } else {
983 if (yych <= '/') goto yy18;
984 if (yych <= '9') goto yy58;
985 goto yy18;
986 }
987 } else {
988 if (yych <= 'E') {
989 if (yych <= ';') goto yy63;
990 if (yych <= 'D') goto yy18;
991 goto yy65;
992 } else {
993 if (yych == 'e') goto yy65;
994 goto yy18;
995 }
996 }
997 yy60:
998 yych = *++YYCURSOR;
999 if (yych <= '/') goto yy18;
1000 if (yych >= ':') goto yy18;
1001 yy61:
1002 ++YYCURSOR;
1003 if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
1004 yych = *YYCURSOR;
1005 if (yych <= ';') {
1006 if (yych <= '/') goto yy18;
1007 if (yych <= '9') goto yy61;
1008 if (yych <= ':') goto yy18;
1009 } else {
1010 if (yych <= 'E') {
1011 if (yych <= 'D') goto yy18;
1012 goto yy65;
1013 } else {
1014 if (yych == 'e') goto yy65;
1015 goto yy18;
1016 }
1017 }
1018 yy63:
1019 ++YYCURSOR;
1020 {
1021 #if SIZEOF_LONG == 4
1022 use_double:
1023 #endif
1024 *p = YYCURSOR;
1025 INIT_PZVAL(*rval);
1026 ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
1027 return 1;
1028 }
1029 yy65:
1030 yych = *++YYCURSOR;
1031 if (yych <= ',') {
1032 if (yych != '+') goto yy18;
1033 } else {
1034 if (yych <= '-') goto yy66;
1035 if (yych <= '/') goto yy18;
1036 if (yych <= '9') goto yy67;
1037 goto yy18;
1038 }
1039 yy66:
1040 yych = *++YYCURSOR;
1041 if (yych <= ',') {
1042 if (yych == '+') goto yy69;
1043 goto yy18;
1044 } else {
1045 if (yych <= '-') goto yy69;
1046 if (yych <= '/') goto yy18;
1047 if (yych >= ':') goto yy18;
1048 }
1049 yy67:
1050 ++YYCURSOR;
1051 if (YYLIMIT <= YYCURSOR) YYFILL(1);
1052 yych = *YYCURSOR;
1053 if (yych <= '/') goto yy18;
1054 if (yych <= '9') goto yy67;
1055 if (yych == ';') goto yy63;
1056 goto yy18;
1057 yy69:
1058 yych = *++YYCURSOR;
1059 if (yych <= '/') goto yy18;
1060 if (yych <= '9') goto yy67;
1061 goto yy18;
1062 yy70:
1063 ++YYCURSOR;
1064 if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
1065 yych = *YYCURSOR;
1066 if (yych <= ';') {
1067 if (yych <= '/') goto yy18;
1068 if (yych <= '9') goto yy70;
1069 if (yych <= ':') goto yy18;
1070 goto yy63;
1071 } else {
1072 if (yych <= 'E') {
1073 if (yych <= 'D') goto yy18;
1074 goto yy65;
1075 } else {
1076 if (yych == 'e') goto yy65;
1077 goto yy18;
1078 }
1079 }
1080 yy72:
1081 yych = *++YYCURSOR;
1082 if (yych != 'F') goto yy18;
1083 yy73:
1084 yych = *++YYCURSOR;
1085 if (yych != ';') goto yy18;
1086 ++YYCURSOR;
1087 {
1088 *p = YYCURSOR;
1089 INIT_PZVAL(*rval);
1090
1091 if (!strncmp(start + 2, "NAN", 3)) {
1092 ZVAL_DOUBLE(*rval, php_get_nan());
1093 } else if (!strncmp(start + 2, "INF", 3)) {
1094 ZVAL_DOUBLE(*rval, php_get_inf());
1095 } else if (!strncmp(start + 2, "-INF", 4)) {
1096 ZVAL_DOUBLE(*rval, -php_get_inf());
1097 }
1098
1099 return 1;
1100 }
1101 yy76:
1102 yych = *++YYCURSOR;
1103 if (yych == 'N') goto yy73;
1104 goto yy18;
1105 yy77:
1106 yych = *++YYCURSOR;
1107 if (yych <= ',') {
1108 if (yych != '+') goto yy18;
1109 } else {
1110 if (yych <= '-') goto yy78;
1111 if (yych <= '/') goto yy18;
1112 if (yych <= '9') goto yy79;
1113 goto yy18;
1114 }
1115 yy78:
1116 yych = *++YYCURSOR;
1117 if (yych <= '/') goto yy18;
1118 if (yych >= ':') goto yy18;
1119 yy79:
1120 ++YYCURSOR;
1121 if (YYLIMIT <= YYCURSOR) YYFILL(1);
1122 yych = *YYCURSOR;
1123 if (yych <= '/') goto yy18;
1124 if (yych <= '9') goto yy79;
1125 if (yych != ';') goto yy18;
1126 ++YYCURSOR;
1127 {
1128 #if SIZEOF_LONG == 4
1129 int digits = YYCURSOR - start - 3;
1130
1131 if (start[2] == '-' || start[2] == '+') {
1132 digits--;
1133 }
1134
1135
1136 if (digits >= MAX_LENGTH_OF_LONG - 1) {
1137 if (digits == MAX_LENGTH_OF_LONG - 1) {
1138 int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
1139
1140 if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
1141 goto use_double;
1142 }
1143 } else {
1144 goto use_double;
1145 }
1146 }
1147 #endif
1148 *p = YYCURSOR;
1149 INIT_PZVAL(*rval);
1150 ZVAL_LONG(*rval, parse_iv(start + 2));
1151 return 1;
1152 }
1153 yy83:
1154 yych = *++YYCURSOR;
1155 if (yych <= '/') goto yy18;
1156 if (yych >= '2') goto yy18;
1157 yych = *++YYCURSOR;
1158 if (yych != ';') goto yy18;
1159 ++YYCURSOR;
1160 {
1161 *p = YYCURSOR;
1162 INIT_PZVAL(*rval);
1163 ZVAL_BOOL(*rval, parse_iv(start + 2));
1164 return 1;
1165 }
1166 yy87:
1167 ++YYCURSOR;
1168 {
1169 *p = YYCURSOR;
1170 INIT_PZVAL(*rval);
1171 ZVAL_NULL(*rval);
1172 return 1;
1173 }
1174 yy89:
1175 yych = *++YYCURSOR;
1176 if (yych <= ',') {
1177 if (yych != '+') goto yy18;
1178 } else {
1179 if (yych <= '-') goto yy90;
1180 if (yych <= '/') goto yy18;
1181 if (yych <= '9') goto yy91;
1182 goto yy18;
1183 }
1184 yy90:
1185 yych = *++YYCURSOR;
1186 if (yych <= '/') goto yy18;
1187 if (yych >= ':') goto yy18;
1188 yy91:
1189 ++YYCURSOR;
1190 if (YYLIMIT <= YYCURSOR) YYFILL(1);
1191 yych = *YYCURSOR;
1192 if (yych <= '/') goto yy18;
1193 if (yych <= '9') goto yy91;
1194 if (yych != ';') goto yy18;
1195 ++YYCURSOR;
1196 {
1197 long id;
1198
1199 *p = YYCURSOR;
1200 if (!var_hash) return 0;
1201
1202 id = parse_iv(start + 2) - 1;
1203 if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
1204 return 0;
1205 }
1206
1207 if (*rval == *rval_ref) return 0;
1208
1209 if (*rval != NULL) {
1210 var_push_dtor_no_addref(var_hash, rval);
1211 }
1212 *rval = *rval_ref;
1213 Z_ADDREF_PP(rval);
1214 Z_UNSET_ISREF_PP(rval);
1215
1216 return 1;
1217 }
1218 yy95:
1219 yych = *++YYCURSOR;
1220 if (yych <= ',') {
1221 if (yych != '+') goto yy18;
1222 } else {
1223 if (yych <= '-') goto yy96;
1224 if (yych <= '/') goto yy18;
1225 if (yych <= '9') goto yy97;
1226 goto yy18;
1227 }
1228 yy96:
1229 yych = *++YYCURSOR;
1230 if (yych <= '/') goto yy18;
1231 if (yych >= ':') goto yy18;
1232 yy97:
1233 ++YYCURSOR;
1234 if (YYLIMIT <= YYCURSOR) YYFILL(1);
1235 yych = *YYCURSOR;
1236 if (yych <= '/') goto yy18;
1237 if (yych <= '9') goto yy97;
1238 if (yych != ';') goto yy18;
1239 ++YYCURSOR;
1240 {
1241 long id;
1242
1243 *p = YYCURSOR;
1244 if (!var_hash) return 0;
1245
1246 id = parse_iv(start + 2) - 1;
1247 if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
1248 return 0;
1249 }
1250
1251 if (*rval != NULL) {
1252 var_push_dtor_no_addref(var_hash, rval);
1253 }
1254 *rval = *rval_ref;
1255 Z_ADDREF_PP(rval);
1256 Z_SET_ISREF_PP(rval);
1257
1258 return 1;
1259 }
1260 }
1261
1262
1263 return 0;
1264 }