1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2006 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP 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.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Author: Sascha Schumann <sascha@schumann.cx> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: var_unserializer.re,v 1.52.2.2.2.3 2007/03/27 09:29:10 tony2001 Exp $ */
20 :
21 : #include "php.h"
22 : #include "ext/standard/php_var.h"
23 : #include "php_incomplete_class.h"
24 :
25 : /* {{{ reference-handling for unserializer: var_* */
26 : #define VAR_ENTRIES_MAX 1024
27 :
28 : typedef struct {
29 : zval *data[VAR_ENTRIES_MAX];
30 : long used_slots;
31 : void *next;
32 : } var_entries;
33 :
34 : static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval)
35 0 : {
36 0 : var_entries *var_hash = var_hashx->first, *prev = NULL;
37 :
38 0 : while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
39 0 : prev = var_hash;
40 0 : var_hash = var_hash->next;
41 : }
42 :
43 0 : if (!var_hash) {
44 0 : var_hash = emalloc(sizeof(var_entries));
45 0 : var_hash->used_slots = 0;
46 0 : var_hash->next = 0;
47 :
48 0 : if (!var_hashx->first)
49 0 : var_hashx->first = var_hash;
50 : else
51 0 : prev->next = var_hash;
52 : }
53 :
54 0 : var_hash->data[var_hash->used_slots++] = *rval;
55 0 : }
56 :
57 : static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
58 0 : {
59 0 : var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
60 :
61 0 : while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
62 0 : prev = var_hash;
63 0 : var_hash = var_hash->next;
64 : }
65 :
66 0 : if (!var_hash) {
67 0 : var_hash = emalloc(sizeof(var_entries));
68 0 : var_hash->used_slots = 0;
69 0 : var_hash->next = 0;
70 :
71 0 : if (!var_hashx->first_dtor)
72 0 : var_hashx->first_dtor = var_hash;
73 : else
74 0 : prev->next = var_hash;
75 : }
76 :
77 0 : (*rval)->refcount++;
78 0 : var_hash->data[var_hash->used_slots++] = *rval;
79 0 : }
80 :
81 : PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval)
82 0 : {
83 : long i;
84 0 : var_entries *var_hash = var_hashx->first;
85 :
86 0 : while (var_hash) {
87 0 : for (i = 0; i < var_hash->used_slots; i++) {
88 0 : if (var_hash->data[i] == ozval) {
89 0 : var_hash->data[i] = *nzval;
90 : /* do not break here */
91 : }
92 : }
93 0 : var_hash = var_hash->next;
94 : }
95 0 : }
96 :
97 : static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store)
98 0 : {
99 0 : var_entries *var_hash = var_hashx->first;
100 :
101 0 : while (id >= VAR_ENTRIES_MAX && var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
102 0 : var_hash = var_hash->next;
103 0 : id -= VAR_ENTRIES_MAX;
104 : }
105 :
106 0 : if (!var_hash) return !SUCCESS;
107 :
108 0 : if (id < 0 || id >= var_hash->used_slots) return !SUCCESS;
109 :
110 0 : *store = &var_hash->data[id];
111 :
112 0 : return SUCCESS;
113 : }
114 :
115 : PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
116 1 : {
117 : void *next;
118 : long i;
119 1 : var_entries *var_hash = var_hashx->first;
120 :
121 2 : while (var_hash) {
122 0 : next = var_hash->next;
123 0 : efree(var_hash);
124 0 : var_hash = next;
125 : }
126 :
127 1 : var_hash = var_hashx->first_dtor;
128 :
129 2 : while (var_hash) {
130 0 : for (i = 0; i < var_hash->used_slots; i++) {
131 0 : zval_ptr_dtor(&var_hash->data[i]);
132 : }
133 0 : next = var_hash->next;
134 0 : efree(var_hash);
135 0 : var_hash = next;
136 : }
137 1 : }
138 :
139 : /* }}} */
140 :
141 : static char *unserialize_str(const unsigned char **p, size_t *len)
142 0 : {
143 : size_t i, j;
144 0 : char *str = safe_emalloc(*len, 1, 1);
145 0 : unsigned char *end = *(unsigned char **)p+*len;
146 :
147 0 : if(end < *p) {
148 0 : efree(str);
149 0 : return NULL;
150 : }
151 :
152 0 : for (i = 0; i < *len && *p < end; i++) {
153 0 : if (**p != '\\') {
154 0 : str[i] = (char)**p;
155 : } else {
156 0 : unsigned char ch = 0;
157 :
158 0 : for (j = 0; j < 2; j++) {
159 0 : (*p)++;
160 0 : if (**p >= '0' && **p <= '9') {
161 0 : ch = (ch << 4) + (**p -'0');
162 0 : } else if (**p >= 'a' && **p <= 'f') {
163 0 : ch = (ch << 4) + (**p -'a'+10);
164 0 : } else if (**p >= 'A' && **p <= 'F') {
165 0 : ch = (ch << 4) + (**p -'A'+10);
166 : } else {
167 0 : efree(str);
168 0 : return NULL;
169 : }
170 : }
171 0 : str[i] = (char)ch;
172 : }
173 0 : (*p)++;
174 : }
175 0 : str[i] = 0;
176 0 : *len = i;
177 0 : return str;
178 : }
179 :
180 : #define YYFILL(n) do { } while (0)
181 : #define YYCTYPE unsigned char
182 : #define YYCURSOR cursor
183 : #define YYLIMIT limit
184 : #define YYMARKER marker
185 :
186 :
187 : /*!re2c
188 : uiv = [+]? [0-9]+;
189 : iv = [+-]? [0-9]+;
190 : nv = [+-]? ([0-9]* "." [0-9]+|[0-9]+ "." [0-9]*);
191 : nvexp = (iv | nv) [eE] [+-]? iv;
192 : any = [\000-\377];
193 : object = [OC];
194 : */
195 :
196 :
197 :
198 : static inline long parse_iv2(const unsigned char *p, const unsigned char **q)
199 0 : {
200 : char cursor;
201 0 : long result = 0;
202 0 : int neg = 0;
203 :
204 0 : switch (*p) {
205 : case '-':
206 0 : neg++;
207 : /* fall-through */
208 : case '+':
209 0 : p++;
210 : }
211 :
212 : while (1) {
213 0 : cursor = (char)*p;
214 0 : if (cursor >= '0' && cursor <= '9') {
215 0 : result = result * 10 + cursor - '0';
216 : } else {
217 : break;
218 : }
219 0 : p++;
220 0 : }
221 0 : if (q) *q = p;
222 0 : if (neg) return -result;
223 0 : return result;
224 : }
225 :
226 : static inline long parse_iv(const unsigned char *p)
227 0 : {
228 0 : return parse_iv2(p, NULL);
229 : }
230 :
231 : /* no need to check for length - re2c already did */
232 : static inline size_t parse_uiv(const unsigned char *p)
233 0 : {
234 : unsigned char cursor;
235 0 : size_t result = 0;
236 :
237 0 : if (*p == '+') {
238 0 : p++;
239 : }
240 :
241 : while (1) {
242 0 : cursor = *p;
243 0 : if (cursor >= '0' && cursor <= '9') {
244 0 : result = result * 10 + (size_t)(cursor - (unsigned char)'0');
245 : } else {
246 : break;
247 : }
248 0 : p++;
249 0 : }
250 0 : return result;
251 : }
252 :
253 : #define UNSERIALIZE_PARAMETER zval **rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC
254 : #define UNSERIALIZE_PASSTHRU rval, p, max, var_hash TSRMLS_CC
255 :
256 : static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long elements)
257 0 : {
258 0 : while (elements-- > 0) {
259 : zval *key, *data, **old_data;
260 :
261 0 : ALLOC_INIT_ZVAL(key);
262 :
263 0 : if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) {
264 0 : zval_dtor(key);
265 0 : FREE_ZVAL(key);
266 0 : return 0;
267 : }
268 :
269 0 : if (Z_TYPE_P(key) != IS_LONG && Z_TYPE_P(key) != IS_STRING) {
270 0 : zval_dtor(key);
271 0 : FREE_ZVAL(key);
272 0 : return 0;
273 : }
274 :
275 0 : ALLOC_INIT_ZVAL(data);
276 :
277 0 : if (!php_var_unserialize(&data, p, max, var_hash TSRMLS_CC)) {
278 0 : zval_dtor(key);
279 0 : FREE_ZVAL(key);
280 0 : zval_dtor(data);
281 0 : FREE_ZVAL(data);
282 0 : return 0;
283 : }
284 :
285 0 : switch (Z_TYPE_P(key)) {
286 : case IS_LONG:
287 0 : if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)==SUCCESS) {
288 0 : var_push_dtor(var_hash, old_data);
289 : }
290 0 : zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL);
291 0 : break;
292 : case IS_STRING:
293 0 : if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
294 0 : var_push_dtor(var_hash, old_data);
295 : }
296 0 : zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
297 : break;
298 : }
299 :
300 0 : zval_dtor(key);
301 0 : FREE_ZVAL(key);
302 :
303 0 : if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
304 0 : (*p)--;
305 0 : return 0;
306 : }
307 : }
308 :
309 0 : return 1;
310 : }
311 :
312 : static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
313 0 : {
314 0 : if (*((*p)++) == '}')
315 0 : return 1;
316 :
317 : #if SOMETHING_NEW_MIGHT_LEAD_TO_CRASH_ENABLE_IF_YOU_ARE_BRAVE
318 : zval_ptr_dtor(rval);
319 : #endif
320 0 : return 0;
321 : }
322 :
323 : static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
324 0 : {
325 : long datalen;
326 :
327 0 : if(ce->unserialize == NULL) {
328 0 : zend_error(E_WARNING, "Class %s has no unserializer", ce->name);
329 0 : return 0;
330 : }
331 :
332 0 : datalen = parse_iv2((*p) + 2, p);
333 :
334 0 : (*p) += 2;
335 :
336 0 : if(datalen < 0 || (*p) + datalen >= max) {
337 0 : zend_error(E_WARNING, "Insufficient data for unserializing - %ld required, %d present", datalen, max - (*p));
338 0 : return 0;
339 : }
340 :
341 0 : if(ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) {
342 0 : return 0;
343 : }
344 :
345 0 : (*p) += datalen;
346 :
347 0 : return finish_nested_data(UNSERIALIZE_PASSTHRU);
348 : }
349 :
350 : static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
351 0 : {
352 : long elements;
353 :
354 0 : elements = parse_iv2((*p) + 2, p);
355 :
356 0 : (*p) += 2;
357 :
358 0 : object_init_ex(*rval, ce);
359 0 : return elements;
360 : }
361 :
362 : static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
363 0 : {
364 0 : zval *retval_ptr = NULL;
365 : zval fname;
366 :
367 0 : if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements)) {
368 0 : return 0;
369 : }
370 :
371 0 : if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
372 : zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) {
373 0 : INIT_PZVAL(&fname);
374 0 : ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0);
375 0 : call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
376 : }
377 :
378 0 : if (retval_ptr)
379 0 : zval_ptr_dtor(&retval_ptr);
380 :
381 0 : return finish_nested_data(UNSERIALIZE_PASSTHRU);
382 :
383 : }
384 :
385 : PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
386 0 : {
387 : const unsigned char *cursor, *limit, *marker, *start;
388 : zval **rval_ref;
389 :
390 0 : limit = cursor = *p;
391 :
392 0 : if (var_hash && cursor[0] != 'R') {
393 0 : var_push(var_hash, rval);
394 : }
395 :
396 0 : start = cursor;
397 :
398 :
399 :
400 : /*!re2c
401 :
402 : "R:" iv ";" {
403 : long id;
404 :
405 0 : *p = YYCURSOR;
406 0 : if (!var_hash) return 0;
407 :
408 0 : id = parse_iv(start + 2) - 1;
409 0 : if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
410 0 : return 0;
411 : }
412 :
413 0 : if (*rval != NULL) {
414 0 : zval_ptr_dtor(rval);
415 : }
416 0 : *rval = *rval_ref;
417 0 : (*rval)->refcount++;
418 0 : (*rval)->is_ref = 1;
419 :
420 0 : return 1;
421 : }
422 :
423 : "r:" iv ";" {
424 : long id;
425 :
426 0 : *p = YYCURSOR;
427 0 : if (!var_hash) return 0;
428 :
429 0 : id = parse_iv(start + 2) - 1;
430 0 : if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
431 0 : return 0;
432 : }
433 :
434 0 : if (*rval == *rval_ref) return 0;
435 :
436 0 : if (*rval != NULL) {
437 0 : zval_ptr_dtor(rval);
438 : }
439 0 : *rval = *rval_ref;
440 0 : (*rval)->refcount++;
441 0 : (*rval)->is_ref = 0;
442 :
443 0 : return 1;
444 : }
445 :
446 : "N;" {
447 0 : *p = YYCURSOR;
448 0 : INIT_PZVAL(*rval);
449 0 : ZVAL_NULL(*rval);
450 0 : return 1;
451 : }
452 :
453 : "b:" [01] ";" {
454 0 : *p = YYCURSOR;
455 0 : INIT_PZVAL(*rval);
456 0 : ZVAL_BOOL(*rval, parse_iv(start + 2));
457 0 : return 1;
458 : }
459 :
460 : "i:" iv ";" {
461 0 : *p = YYCURSOR;
462 0 : INIT_PZVAL(*rval);
463 0 : ZVAL_LONG(*rval, parse_iv(start + 2));
464 0 : return 1;
465 : }
466 :
467 : "d:" ("NAN" | "-"? "INF") ";" {
468 0 : *p = YYCURSOR;
469 0 : INIT_PZVAL(*rval);
470 :
471 0 : if (!strncmp(start + 2, "NAN", 3)) {
472 0 : ZVAL_DOUBLE(*rval, php_get_nan());
473 0 : } else if (!strncmp(start + 2, "INF", 3)) {
474 0 : ZVAL_DOUBLE(*rval, php_get_inf());
475 0 : } else if (!strncmp(start + 2, "-INF", 4)) {
476 0 : ZVAL_DOUBLE(*rval, -php_get_inf());
477 : }
478 :
479 0 : return 1;
480 : }
481 :
482 : "d:" (iv | nv | nvexp) ";" {
483 0 : *p = YYCURSOR;
484 0 : INIT_PZVAL(*rval);
485 0 : ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
486 0 : return 1;
487 : }
488 :
489 : "s:" uiv ":" ["] {
490 : size_t len, maxlen;
491 : char *str;
492 :
493 0 : len = parse_uiv(start + 2);
494 0 : maxlen = max - YYCURSOR;
495 0 : if (maxlen < len) {
496 0 : *p = start + 2;
497 0 : return 0;
498 : }
499 :
500 0 : str = (char*)YYCURSOR;
501 :
502 0 : YYCURSOR += len;
503 :
504 0 : if (*(YYCURSOR) != '"') {
505 0 : *p = YYCURSOR;
506 0 : return 0;
507 : }
508 :
509 0 : YYCURSOR += 2;
510 0 : *p = YYCURSOR;
511 :
512 0 : INIT_PZVAL(*rval);
513 0 : ZVAL_STRINGL(*rval, str, len, 1);
514 0 : return 1;
515 : }
516 :
517 : "S:" uiv ":" ["] {
518 : size_t len, maxlen;
519 : char *str;
520 :
521 0 : len = parse_uiv(start + 2);
522 0 : maxlen = max - YYCURSOR;
523 0 : if (maxlen < len) {
524 0 : *p = start + 2;
525 0 : return 0;
526 : }
527 :
528 0 : if ((str = unserialize_str(&YYCURSOR, &len)) == NULL) {
529 0 : return 0;
530 : }
531 :
532 0 : if (*(YYCURSOR) != '"') {
533 0 : efree(str);
534 0 : *p = YYCURSOR;
535 0 : return 0;
536 : }
537 :
538 0 : YYCURSOR += 2;
539 0 : *p = YYCURSOR;
540 :
541 0 : INIT_PZVAL(*rval);
542 0 : ZVAL_STRINGL(*rval, str, len, 0);
543 0 : return 1;
544 : }
545 :
546 : "a:" uiv ":" "{" {
547 0 : long elements = parse_iv(start + 2);
548 : /* use iv() not uiv() in order to check data range */
549 0 : *p = YYCURSOR;
550 :
551 0 : if (elements < 0) {
552 0 : return 0;
553 : }
554 :
555 0 : INIT_PZVAL(*rval);
556 0 : Z_TYPE_PP(rval) = IS_ARRAY;
557 0 : ALLOC_HASHTABLE(Z_ARRVAL_PP(rval));
558 :
559 0 : zend_hash_init(Z_ARRVAL_PP(rval), elements + 1, NULL, ZVAL_PTR_DTOR, 0);
560 :
561 0 : if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements)) {
562 0 : return 0;
563 : }
564 :
565 0 : return finish_nested_data(UNSERIALIZE_PASSTHRU);
566 : }
567 :
568 : "o:" iv ":" ["] {
569 :
570 0 : INIT_PZVAL(*rval);
571 :
572 0 : return object_common2(UNSERIALIZE_PASSTHRU,
573 : object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
574 : }
575 :
576 : object ":" uiv ":" ["] {
577 : size_t len, len2, len3, maxlen;
578 : long elements;
579 : char *class_name;
580 : zend_class_entry *ce;
581 : zend_class_entry **pce;
582 0 : int incomplete_class = 0;
583 :
584 0 : int custom_object = 0;
585 :
586 : zval *user_func;
587 : zval *retval_ptr;
588 : zval **args[1];
589 : zval *arg_func_name;
590 :
591 0 : if(*start == 'C') {
592 0 : custom_object = 1;
593 : }
594 :
595 0 : INIT_PZVAL(*rval);
596 0 : len2 = len = parse_uiv(start + 2);
597 0 : maxlen = max - YYCURSOR;
598 0 : if (maxlen < len || len == 0) {
599 0 : *p = start + 2;
600 0 : return 0;
601 : }
602 :
603 0 : class_name = (char*)YYCURSOR;
604 :
605 0 : YYCURSOR += len;
606 :
607 0 : if (*(YYCURSOR) != '"') {
608 0 : *p = YYCURSOR;
609 0 : return 0;
610 : }
611 0 : if (*(YYCURSOR+1) != ':') {
612 0 : *p = YYCURSOR+1;
613 0 : return 0;
614 : }
615 :
616 0 : 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");
617 0 : if (len3 != len)
618 : {
619 0 : *p = YYCURSOR + len3 - len;
620 0 : return 0;
621 : }
622 :
623 0 : class_name = estrndup(class_name, len);
624 :
625 : do {
626 : /* Try to find class directly */
627 0 : if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
628 0 : ce = *pce;
629 0 : break;
630 : }
631 :
632 : /* Check for unserialize callback */
633 0 : if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
634 0 : incomplete_class = 1;
635 0 : ce = PHP_IC_ENTRY;
636 0 : break;
637 : }
638 :
639 : /* Call unserialize callback */
640 0 : MAKE_STD_ZVAL(user_func);
641 0 : ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
642 0 : args[0] = &arg_func_name;
643 0 : MAKE_STD_ZVAL(arg_func_name);
644 0 : ZVAL_STRING(arg_func_name, class_name, 1);
645 0 : if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
646 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
647 0 : incomplete_class = 1;
648 0 : ce = PHP_IC_ENTRY;
649 0 : zval_ptr_dtor(&user_func);
650 0 : zval_ptr_dtor(&arg_func_name);
651 0 : break;
652 : }
653 0 : if (retval_ptr) {
654 0 : zval_ptr_dtor(&retval_ptr);
655 : }
656 :
657 : /* The callback function may have defined the class */
658 0 : if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
659 0 : ce = *pce;
660 : } else {
661 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val);
662 0 : incomplete_class = 1;
663 0 : ce = PHP_IC_ENTRY;
664 : }
665 :
666 0 : zval_ptr_dtor(&user_func);
667 0 : zval_ptr_dtor(&arg_func_name);
668 0 : break;
669 : } while (1);
670 :
671 0 : *p = YYCURSOR;
672 :
673 0 : if(custom_object) {
674 0 : efree(class_name);
675 0 : return object_custom(UNSERIALIZE_PASSTHRU, ce);
676 : }
677 :
678 0 : elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
679 :
680 0 : if (incomplete_class) {
681 0 : php_store_class_name(*rval, class_name, len2);
682 : }
683 0 : efree(class_name);
684 :
685 0 : return object_common2(UNSERIALIZE_PASSTHRU, elements);
686 : }
687 :
688 : "}" {
689 : /* this is the case where we have less data than planned */
690 0 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
691 0 : return 0; /* not sure if it should be 0 or 1 here? */
692 : }
693 :
694 0 : any { return 0; }
695 :
696 : */
697 :
698 : return 0;
699 : }
|