Annotation of embedaddon/php/ext/standard/var_unserializer.c, revision 1.1.1.3
1.1.1.3 ! misho 1: /* Generated by re2c 0.13.5 on Sat Mar 9 22:33:09 2013 */
1.1 misho 2: /*
3: +----------------------------------------------------------------------+
4: | PHP Version 5 |
5: +----------------------------------------------------------------------+
1.1.1.3 ! misho 6: | Copyright (c) 1997-2013 The PHP Group |
1.1 misho 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:
1.1.1.3 ! misho 397: if (retval_ptr) {
1.1 misho 398: zval_ptr_dtor(&retval_ptr);
1.1.1.3 ! misho 399: }
! 400:
! 401: if (EG(exception)) {
! 402: return 0;
! 403: }
1.1 misho 404:
405: return finish_nested_data(UNSERIALIZE_PASSTHRU);
406:
407: }
1.1.1.2 misho 408: #ifdef PHP_WIN32
409: # pragma optimize("", on)
410: #endif
1.1 misho 411:
412: PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
413: {
414: const unsigned char *cursor, *limit, *marker, *start;
415: zval **rval_ref;
416:
1.1.1.2 misho 417: limit = max;
418: cursor = *p;
419:
420: if (YYCURSOR >= YYLIMIT) {
421: return 0;
422: }
1.1 misho 423:
424: if (var_hash && cursor[0] != 'R') {
425: var_push(var_hash, rval);
426: }
427:
428: start = cursor;
429:
430:
431:
432:
433: {
434: YYCTYPE yych;
435: static const unsigned char yybm[] = {
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: 128, 128, 128, 128, 128, 128, 128, 128,
443: 128, 128, 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: 0, 0, 0, 0, 0, 0, 0, 0,
464: 0, 0, 0, 0, 0, 0, 0, 0,
465: 0, 0, 0, 0, 0, 0, 0, 0,
466: 0, 0, 0, 0, 0, 0, 0, 0,
467: 0, 0, 0, 0, 0, 0, 0, 0,
468: };
469:
470: if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
471: yych = *YYCURSOR;
472: switch (yych) {
473: case 'C':
474: case 'O': goto yy13;
475: case 'N': goto yy5;
476: case 'R': goto yy2;
477: case 'S': goto yy10;
478: case 'a': goto yy11;
479: case 'b': goto yy6;
480: case 'd': goto yy8;
481: case 'i': goto yy7;
482: case 'o': goto yy12;
483: case 'r': goto yy4;
484: case 's': goto yy9;
485: case '}': goto yy14;
486: default: goto yy16;
487: }
488: yy2:
489: yych = *(YYMARKER = ++YYCURSOR);
490: if (yych == ':') goto yy95;
491: yy3:
492: { return 0; }
493: yy4:
494: yych = *(YYMARKER = ++YYCURSOR);
495: if (yych == ':') goto yy89;
496: goto yy3;
497: yy5:
498: yych = *++YYCURSOR;
499: if (yych == ';') goto yy87;
500: goto yy3;
501: yy6:
502: yych = *(YYMARKER = ++YYCURSOR);
503: if (yych == ':') goto yy83;
504: goto yy3;
505: yy7:
506: yych = *(YYMARKER = ++YYCURSOR);
507: if (yych == ':') goto yy77;
508: goto yy3;
509: yy8:
510: yych = *(YYMARKER = ++YYCURSOR);
511: if (yych == ':') goto yy53;
512: goto yy3;
513: yy9:
514: yych = *(YYMARKER = ++YYCURSOR);
515: if (yych == ':') goto yy46;
516: goto yy3;
517: yy10:
518: yych = *(YYMARKER = ++YYCURSOR);
519: if (yych == ':') goto yy39;
520: goto yy3;
521: yy11:
522: yych = *(YYMARKER = ++YYCURSOR);
523: if (yych == ':') goto yy32;
524: goto yy3;
525: yy12:
526: yych = *(YYMARKER = ++YYCURSOR);
527: if (yych == ':') goto yy25;
528: goto yy3;
529: yy13:
530: yych = *(YYMARKER = ++YYCURSOR);
531: if (yych == ':') goto yy17;
532: goto yy3;
533: yy14:
534: ++YYCURSOR;
535: {
536: /* this is the case where we have less data than planned */
537: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
538: return 0; /* not sure if it should be 0 or 1 here? */
539: }
540: yy16:
541: yych = *++YYCURSOR;
542: goto yy3;
543: yy17:
544: yych = *++YYCURSOR;
545: if (yybm[0+yych] & 128) {
546: goto yy20;
547: }
548: if (yych == '+') goto yy19;
549: yy18:
550: YYCURSOR = YYMARKER;
551: goto yy3;
552: yy19:
553: yych = *++YYCURSOR;
554: if (yybm[0+yych] & 128) {
555: goto yy20;
556: }
557: goto yy18;
558: yy20:
559: ++YYCURSOR;
560: if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
561: yych = *YYCURSOR;
562: if (yybm[0+yych] & 128) {
563: goto yy20;
564: }
565: if (yych != ':') goto yy18;
566: yych = *++YYCURSOR;
567: if (yych != '"') goto yy18;
568: ++YYCURSOR;
569: {
570: size_t len, len2, len3, maxlen;
571: long elements;
572: char *class_name;
573: zend_class_entry *ce;
574: zend_class_entry **pce;
575: int incomplete_class = 0;
576:
577: int custom_object = 0;
578:
579: zval *user_func;
580: zval *retval_ptr;
581: zval **args[1];
582: zval *arg_func_name;
583:
584: if (*start == 'C') {
585: custom_object = 1;
586: }
587:
588: INIT_PZVAL(*rval);
589: len2 = len = parse_uiv(start + 2);
590: maxlen = max - YYCURSOR;
591: if (maxlen < len || len == 0) {
592: *p = start + 2;
593: return 0;
594: }
595:
596: class_name = (char*)YYCURSOR;
597:
598: YYCURSOR += len;
599:
600: if (*(YYCURSOR) != '"') {
601: *p = YYCURSOR;
602: return 0;
603: }
604: if (*(YYCURSOR+1) != ':') {
605: *p = YYCURSOR+1;
606: return 0;
607: }
608:
609: 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\\");
610: if (len3 != len)
611: {
612: *p = YYCURSOR + len3 - len;
613: return 0;
614: }
615:
616: class_name = estrndup(class_name, len);
617:
618: do {
619: /* Try to find class directly */
1.1.1.3 ! misho 620: BG(serialize_lock) = 1;
1.1 misho 621: if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
1.1.1.3 ! misho 622: BG(serialize_lock) = 0;
! 623: if (EG(exception)) {
! 624: efree(class_name);
! 625: return 0;
! 626: }
1.1 misho 627: ce = *pce;
628: break;
629: }
1.1.1.3 ! misho 630: BG(serialize_lock) = 0;
! 631:
! 632: if (EG(exception)) {
! 633: efree(class_name);
! 634: return 0;
! 635: }
1.1 misho 636:
637: /* Check for unserialize callback */
638: if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
639: incomplete_class = 1;
640: ce = PHP_IC_ENTRY;
641: break;
642: }
643:
644: /* Call unserialize callback */
645: MAKE_STD_ZVAL(user_func);
646: ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
647: args[0] = &arg_func_name;
648: MAKE_STD_ZVAL(arg_func_name);
649: ZVAL_STRING(arg_func_name, class_name, 1);
1.1.1.3 ! misho 650: BG(serialize_lock) = 1;
1.1 misho 651: if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
1.1.1.3 ! misho 652: BG(serialize_lock) = 0;
! 653: if (EG(exception)) {
! 654: efree(class_name);
! 655: zval_ptr_dtor(&user_func);
! 656: zval_ptr_dtor(&arg_func_name);
! 657: return 0;
! 658: }
1.1 misho 659: php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
660: incomplete_class = 1;
661: ce = PHP_IC_ENTRY;
662: zval_ptr_dtor(&user_func);
663: zval_ptr_dtor(&arg_func_name);
664: break;
665: }
1.1.1.3 ! misho 666: BG(serialize_lock) = 0;
1.1 misho 667: if (retval_ptr) {
668: zval_ptr_dtor(&retval_ptr);
669: }
1.1.1.3 ! misho 670: if (EG(exception)) {
! 671: efree(class_name);
! 672: zval_ptr_dtor(&user_func);
! 673: zval_ptr_dtor(&arg_func_name);
! 674: return 0;
! 675: }
1.1 misho 676:
677: /* The callback function may have defined the class */
678: if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
679: ce = *pce;
680: } else {
681: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val);
682: incomplete_class = 1;
683: ce = PHP_IC_ENTRY;
684: }
685:
686: zval_ptr_dtor(&user_func);
687: zval_ptr_dtor(&arg_func_name);
688: break;
689: } while (1);
690:
691: *p = YYCURSOR;
692:
693: if (custom_object) {
694: int ret = object_custom(UNSERIALIZE_PASSTHRU, ce);
695:
696: if (ret && incomplete_class) {
697: php_store_class_name(*rval, class_name, len2);
698: }
699: efree(class_name);
700: return ret;
701: }
702:
703: elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
704:
705: if (incomplete_class) {
706: php_store_class_name(*rval, class_name, len2);
707: }
708: efree(class_name);
709:
710: return object_common2(UNSERIALIZE_PASSTHRU, elements);
711: }
712: yy25:
713: yych = *++YYCURSOR;
714: if (yych <= ',') {
715: if (yych != '+') goto yy18;
716: } else {
717: if (yych <= '-') goto yy26;
718: if (yych <= '/') goto yy18;
719: if (yych <= '9') goto yy27;
720: goto yy18;
721: }
722: yy26:
723: yych = *++YYCURSOR;
724: if (yych <= '/') goto yy18;
725: if (yych >= ':') goto yy18;
726: yy27:
727: ++YYCURSOR;
728: if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
729: yych = *YYCURSOR;
730: if (yych <= '/') goto yy18;
731: if (yych <= '9') goto yy27;
732: if (yych >= ';') goto yy18;
733: yych = *++YYCURSOR;
734: if (yych != '"') goto yy18;
735: ++YYCURSOR;
736: {
737:
738: INIT_PZVAL(*rval);
739:
740: return object_common2(UNSERIALIZE_PASSTHRU,
741: object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
742: }
743: yy32:
744: yych = *++YYCURSOR;
745: if (yych == '+') goto yy33;
746: if (yych <= '/') goto yy18;
747: if (yych <= '9') goto yy34;
748: goto yy18;
749: yy33:
750: yych = *++YYCURSOR;
751: if (yych <= '/') goto yy18;
752: if (yych >= ':') goto yy18;
753: yy34:
754: ++YYCURSOR;
755: if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
756: yych = *YYCURSOR;
757: if (yych <= '/') goto yy18;
758: if (yych <= '9') goto yy34;
759: if (yych >= ';') goto yy18;
760: yych = *++YYCURSOR;
761: if (yych != '{') goto yy18;
762: ++YYCURSOR;
763: {
764: long elements = parse_iv(start + 2);
765: /* use iv() not uiv() in order to check data range */
766: *p = YYCURSOR;
767:
768: if (elements < 0) {
769: return 0;
770: }
771:
772: INIT_PZVAL(*rval);
773:
774: array_init_size(*rval, elements);
775:
776: if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) {
777: return 0;
778: }
779:
780: return finish_nested_data(UNSERIALIZE_PASSTHRU);
781: }
782: yy39:
783: yych = *++YYCURSOR;
784: if (yych == '+') goto yy40;
785: if (yych <= '/') goto yy18;
786: if (yych <= '9') goto yy41;
787: goto yy18;
788: yy40:
789: yych = *++YYCURSOR;
790: if (yych <= '/') goto yy18;
791: if (yych >= ':') goto yy18;
792: yy41:
793: ++YYCURSOR;
794: if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
795: yych = *YYCURSOR;
796: if (yych <= '/') goto yy18;
797: if (yych <= '9') goto yy41;
798: if (yych >= ';') goto yy18;
799: yych = *++YYCURSOR;
800: if (yych != '"') goto yy18;
801: ++YYCURSOR;
802: {
803: size_t len, maxlen;
804: char *str;
805:
806: len = parse_uiv(start + 2);
807: maxlen = max - YYCURSOR;
808: if (maxlen < len) {
809: *p = start + 2;
810: return 0;
811: }
812:
813: if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) {
814: return 0;
815: }
816:
817: if (*(YYCURSOR) != '"') {
818: efree(str);
819: *p = YYCURSOR;
820: return 0;
821: }
822:
823: YYCURSOR += 2;
824: *p = YYCURSOR;
825:
826: INIT_PZVAL(*rval);
827: ZVAL_STRINGL(*rval, str, len, 0);
828: return 1;
829: }
830: yy46:
831: yych = *++YYCURSOR;
832: if (yych == '+') goto yy47;
833: if (yych <= '/') goto yy18;
834: if (yych <= '9') goto yy48;
835: goto yy18;
836: yy47:
837: yych = *++YYCURSOR;
838: if (yych <= '/') goto yy18;
839: if (yych >= ':') goto yy18;
840: yy48:
841: ++YYCURSOR;
842: if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
843: yych = *YYCURSOR;
844: if (yych <= '/') goto yy18;
845: if (yych <= '9') goto yy48;
846: if (yych >= ';') goto yy18;
847: yych = *++YYCURSOR;
848: if (yych != '"') goto yy18;
849: ++YYCURSOR;
850: {
851: size_t len, maxlen;
852: char *str;
853:
854: len = parse_uiv(start + 2);
855: maxlen = max - YYCURSOR;
856: if (maxlen < len) {
857: *p = start + 2;
858: return 0;
859: }
860:
861: str = (char*)YYCURSOR;
862:
863: YYCURSOR += len;
864:
865: if (*(YYCURSOR) != '"') {
866: *p = YYCURSOR;
867: return 0;
868: }
869:
870: YYCURSOR += 2;
871: *p = YYCURSOR;
872:
873: INIT_PZVAL(*rval);
874: ZVAL_STRINGL(*rval, str, len, 1);
875: return 1;
876: }
877: yy53:
878: yych = *++YYCURSOR;
879: if (yych <= '/') {
880: if (yych <= ',') {
881: if (yych == '+') goto yy57;
882: goto yy18;
883: } else {
884: if (yych <= '-') goto yy55;
885: if (yych <= '.') goto yy60;
886: goto yy18;
887: }
888: } else {
889: if (yych <= 'I') {
890: if (yych <= '9') goto yy58;
891: if (yych <= 'H') goto yy18;
892: goto yy56;
893: } else {
894: if (yych != 'N') goto yy18;
895: }
896: }
897: yych = *++YYCURSOR;
898: if (yych == 'A') goto yy76;
899: goto yy18;
900: yy55:
901: yych = *++YYCURSOR;
902: if (yych <= '/') {
903: if (yych == '.') goto yy60;
904: goto yy18;
905: } else {
906: if (yych <= '9') goto yy58;
907: if (yych != 'I') goto yy18;
908: }
909: yy56:
910: yych = *++YYCURSOR;
911: if (yych == 'N') goto yy72;
912: goto yy18;
913: yy57:
914: yych = *++YYCURSOR;
915: if (yych == '.') goto yy60;
916: if (yych <= '/') goto yy18;
917: if (yych >= ':') goto yy18;
918: yy58:
919: ++YYCURSOR;
920: if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
921: yych = *YYCURSOR;
922: if (yych <= ':') {
923: if (yych <= '.') {
924: if (yych <= '-') goto yy18;
925: goto yy70;
926: } else {
927: if (yych <= '/') goto yy18;
928: if (yych <= '9') goto yy58;
929: goto yy18;
930: }
931: } else {
932: if (yych <= 'E') {
933: if (yych <= ';') goto yy63;
934: if (yych <= 'D') goto yy18;
935: goto yy65;
936: } else {
937: if (yych == 'e') goto yy65;
938: goto yy18;
939: }
940: }
941: yy60:
942: yych = *++YYCURSOR;
943: if (yych <= '/') goto yy18;
944: if (yych >= ':') goto yy18;
945: yy61:
946: ++YYCURSOR;
947: if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
948: yych = *YYCURSOR;
949: if (yych <= ';') {
950: if (yych <= '/') goto yy18;
951: if (yych <= '9') goto yy61;
952: if (yych <= ':') goto yy18;
953: } else {
954: if (yych <= 'E') {
955: if (yych <= 'D') goto yy18;
956: goto yy65;
957: } else {
958: if (yych == 'e') goto yy65;
959: goto yy18;
960: }
961: }
962: yy63:
963: ++YYCURSOR;
964: {
965: #if SIZEOF_LONG == 4
966: use_double:
967: #endif
968: *p = YYCURSOR;
969: INIT_PZVAL(*rval);
970: ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
971: return 1;
972: }
973: yy65:
974: yych = *++YYCURSOR;
975: if (yych <= ',') {
976: if (yych != '+') goto yy18;
977: } else {
978: if (yych <= '-') goto yy66;
979: if (yych <= '/') goto yy18;
980: if (yych <= '9') goto yy67;
981: goto yy18;
982: }
983: yy66:
984: yych = *++YYCURSOR;
985: if (yych <= ',') {
986: if (yych == '+') goto yy69;
987: goto yy18;
988: } else {
989: if (yych <= '-') goto yy69;
990: if (yych <= '/') goto yy18;
991: if (yych >= ':') goto yy18;
992: }
993: yy67:
994: ++YYCURSOR;
995: if (YYLIMIT <= YYCURSOR) YYFILL(1);
996: yych = *YYCURSOR;
997: if (yych <= '/') goto yy18;
998: if (yych <= '9') goto yy67;
999: if (yych == ';') goto yy63;
1000: goto yy18;
1001: yy69:
1002: yych = *++YYCURSOR;
1003: if (yych <= '/') goto yy18;
1004: if (yych <= '9') goto yy67;
1005: goto yy18;
1006: yy70:
1007: ++YYCURSOR;
1008: if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
1009: yych = *YYCURSOR;
1010: if (yych <= ';') {
1011: if (yych <= '/') goto yy18;
1012: if (yych <= '9') goto yy70;
1013: if (yych <= ':') goto yy18;
1014: goto yy63;
1015: } else {
1016: if (yych <= 'E') {
1017: if (yych <= 'D') goto yy18;
1018: goto yy65;
1019: } else {
1020: if (yych == 'e') goto yy65;
1021: goto yy18;
1022: }
1023: }
1024: yy72:
1025: yych = *++YYCURSOR;
1026: if (yych != 'F') goto yy18;
1027: yy73:
1028: yych = *++YYCURSOR;
1029: if (yych != ';') goto yy18;
1030: ++YYCURSOR;
1031: {
1032: *p = YYCURSOR;
1033: INIT_PZVAL(*rval);
1034:
1035: if (!strncmp(start + 2, "NAN", 3)) {
1036: ZVAL_DOUBLE(*rval, php_get_nan());
1037: } else if (!strncmp(start + 2, "INF", 3)) {
1038: ZVAL_DOUBLE(*rval, php_get_inf());
1039: } else if (!strncmp(start + 2, "-INF", 4)) {
1040: ZVAL_DOUBLE(*rval, -php_get_inf());
1041: }
1042:
1043: return 1;
1044: }
1045: yy76:
1046: yych = *++YYCURSOR;
1047: if (yych == 'N') goto yy73;
1048: goto yy18;
1049: yy77:
1050: yych = *++YYCURSOR;
1051: if (yych <= ',') {
1052: if (yych != '+') goto yy18;
1053: } else {
1054: if (yych <= '-') goto yy78;
1055: if (yych <= '/') goto yy18;
1056: if (yych <= '9') goto yy79;
1057: goto yy18;
1058: }
1059: yy78:
1060: yych = *++YYCURSOR;
1061: if (yych <= '/') goto yy18;
1062: if (yych >= ':') goto yy18;
1063: yy79:
1064: ++YYCURSOR;
1065: if (YYLIMIT <= YYCURSOR) YYFILL(1);
1066: yych = *YYCURSOR;
1067: if (yych <= '/') goto yy18;
1068: if (yych <= '9') goto yy79;
1069: if (yych != ';') goto yy18;
1070: ++YYCURSOR;
1071: {
1072: #if SIZEOF_LONG == 4
1073: int digits = YYCURSOR - start - 3;
1074:
1075: if (start[2] == '-' || start[2] == '+') {
1076: digits--;
1077: }
1078:
1079: /* Use double for large long values that were serialized on a 64-bit system */
1080: if (digits >= MAX_LENGTH_OF_LONG - 1) {
1081: if (digits == MAX_LENGTH_OF_LONG - 1) {
1082: int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
1083:
1084: if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
1085: goto use_double;
1086: }
1087: } else {
1088: goto use_double;
1089: }
1090: }
1091: #endif
1092: *p = YYCURSOR;
1093: INIT_PZVAL(*rval);
1094: ZVAL_LONG(*rval, parse_iv(start + 2));
1095: return 1;
1096: }
1097: yy83:
1098: yych = *++YYCURSOR;
1099: if (yych <= '/') goto yy18;
1100: if (yych >= '2') goto yy18;
1101: yych = *++YYCURSOR;
1102: if (yych != ';') goto yy18;
1103: ++YYCURSOR;
1104: {
1105: *p = YYCURSOR;
1106: INIT_PZVAL(*rval);
1107: ZVAL_BOOL(*rval, parse_iv(start + 2));
1108: return 1;
1109: }
1110: yy87:
1111: ++YYCURSOR;
1112: {
1113: *p = YYCURSOR;
1114: INIT_PZVAL(*rval);
1115: ZVAL_NULL(*rval);
1116: return 1;
1117: }
1118: yy89:
1119: yych = *++YYCURSOR;
1120: if (yych <= ',') {
1121: if (yych != '+') goto yy18;
1122: } else {
1123: if (yych <= '-') goto yy90;
1124: if (yych <= '/') goto yy18;
1125: if (yych <= '9') goto yy91;
1126: goto yy18;
1127: }
1128: yy90:
1129: yych = *++YYCURSOR;
1130: if (yych <= '/') goto yy18;
1131: if (yych >= ':') goto yy18;
1132: yy91:
1133: ++YYCURSOR;
1134: if (YYLIMIT <= YYCURSOR) YYFILL(1);
1135: yych = *YYCURSOR;
1136: if (yych <= '/') goto yy18;
1137: if (yych <= '9') goto yy91;
1138: if (yych != ';') goto yy18;
1139: ++YYCURSOR;
1140: {
1141: long id;
1142:
1143: *p = YYCURSOR;
1144: if (!var_hash) return 0;
1145:
1146: id = parse_iv(start + 2) - 1;
1147: if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
1148: return 0;
1149: }
1150:
1151: if (*rval == *rval_ref) return 0;
1152:
1153: if (*rval != NULL) {
1154: zval_ptr_dtor(rval);
1155: }
1156: *rval = *rval_ref;
1157: Z_ADDREF_PP(rval);
1158: Z_UNSET_ISREF_PP(rval);
1159:
1160: return 1;
1161: }
1162: yy95:
1163: yych = *++YYCURSOR;
1164: if (yych <= ',') {
1165: if (yych != '+') goto yy18;
1166: } else {
1167: if (yych <= '-') goto yy96;
1168: if (yych <= '/') goto yy18;
1169: if (yych <= '9') goto yy97;
1170: goto yy18;
1171: }
1172: yy96:
1173: yych = *++YYCURSOR;
1174: if (yych <= '/') goto yy18;
1175: if (yych >= ':') goto yy18;
1176: yy97:
1177: ++YYCURSOR;
1178: if (YYLIMIT <= YYCURSOR) YYFILL(1);
1179: yych = *YYCURSOR;
1180: if (yych <= '/') goto yy18;
1181: if (yych <= '9') goto yy97;
1182: if (yych != ';') goto yy18;
1183: ++YYCURSOR;
1184: {
1185: long id;
1186:
1187: *p = YYCURSOR;
1188: if (!var_hash) return 0;
1189:
1190: id = parse_iv(start + 2) - 1;
1191: if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
1192: return 0;
1193: }
1194:
1195: if (*rval != NULL) {
1196: zval_ptr_dtor(rval);
1197: }
1198: *rval = *rval_ref;
1199: Z_ADDREF_PP(rval);
1200: Z_SET_ISREF_PP(rval);
1201:
1202: return 1;
1203: }
1204: }
1205:
1206:
1207: return 0;
1208: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>