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