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