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