Return to var_unserializer.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / standard |
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: }