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