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