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