Back to index

php5  5.3.10
var_unserializer.c
Go to the documentation of this file.
00001 /* Generated by re2c 0.13.5 on Wed Sep 28 15:40:15 2011 */
00002 /*
00003   +----------------------------------------------------------------------+
00004   | PHP Version 5                                                        |
00005   +----------------------------------------------------------------------+
00006   | Copyright (c) 1997-2012 The PHP Group                                |
00007   +----------------------------------------------------------------------+
00008   | This source file is subject to version 3.01 of the PHP license,      |
00009   | that is bundled with this package in the file LICENSE, and is        |
00010   | available through the world-wide-web at the following url:           |
00011   | http://www.php.net/license/3_01.txt                                  |
00012   | If you did not receive a copy of the PHP license and are unable to   |
00013   | obtain it through the world-wide-web, please send a note to          |
00014   | license@php.net so we can mail you a copy immediately.               |
00015   +----------------------------------------------------------------------+
00016   | Author: Sascha Schumann <sascha@schumann.cx>                         |
00017   +----------------------------------------------------------------------+
00018 */
00019 
00020 /* $Id: var_unserializer.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #include "php.h"
00023 #include "ext/standard/php_var.h"
00024 #include "php_incomplete_class.h"
00025 
00026 /* {{{ reference-handling for unserializer: var_* */
00027 #define VAR_ENTRIES_MAX 1024
00028 
00029 typedef struct {
00030        zval *data[VAR_ENTRIES_MAX];
00031        long used_slots;
00032        void *next;
00033 } var_entries;
00034 
00035 static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval)
00036 {
00037        var_entries *var_hash = var_hashx->first, *prev = NULL;
00038 
00039        while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
00040               prev = var_hash;
00041               var_hash = var_hash->next;
00042        }
00043 
00044        if (!var_hash) {
00045               var_hash = emalloc(sizeof(var_entries));
00046               var_hash->used_slots = 0;
00047               var_hash->next = 0;
00048 
00049               if (!var_hashx->first)
00050                      var_hashx->first = var_hash;
00051               else
00052                      prev->next = var_hash;
00053        }
00054 
00055        var_hash->data[var_hash->used_slots++] = *rval;
00056 }
00057 
00058 PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
00059 {
00060        var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
00061 
00062        while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
00063               prev = var_hash;
00064               var_hash = var_hash->next;
00065        }
00066 
00067        if (!var_hash) {
00068               var_hash = emalloc(sizeof(var_entries));
00069               var_hash->used_slots = 0;
00070               var_hash->next = 0;
00071 
00072               if (!var_hashx->first_dtor)
00073                      var_hashx->first_dtor = var_hash;
00074               else
00075                      prev->next = var_hash;
00076        }
00077 
00078        Z_ADDREF_PP(rval);
00079        var_hash->data[var_hash->used_slots++] = *rval;
00080 }
00081 
00082 PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval)
00083 {
00084        long i;
00085        var_entries *var_hash = var_hashx->first;
00086        
00087        while (var_hash) {
00088               for (i = 0; i < var_hash->used_slots; i++) {
00089                      if (var_hash->data[i] == ozval) {
00090                             var_hash->data[i] = *nzval;
00091                             /* do not break here */
00092                      }
00093               }
00094               var_hash = var_hash->next;
00095        }
00096 }
00097 
00098 static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store)
00099 {
00100        var_entries *var_hash = var_hashx->first;
00101        
00102        while (id >= VAR_ENTRIES_MAX && var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
00103               var_hash = var_hash->next;
00104               id -= VAR_ENTRIES_MAX;
00105        }
00106 
00107        if (!var_hash) return !SUCCESS;
00108 
00109        if (id < 0 || id >= var_hash->used_slots) return !SUCCESS;
00110 
00111        *store = &var_hash->data[id];
00112 
00113        return SUCCESS;
00114 }
00115 
00116 PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
00117 {
00118        void *next;
00119        long i;
00120        var_entries *var_hash = var_hashx->first;
00121        
00122        while (var_hash) {
00123               next = var_hash->next;
00124               efree(var_hash);
00125               var_hash = next;
00126        }
00127 
00128        var_hash = var_hashx->first_dtor;
00129        
00130        while (var_hash) {
00131               for (i = 0; i < var_hash->used_slots; i++) {
00132                      zval_ptr_dtor(&var_hash->data[i]);
00133               }
00134               next = var_hash->next;
00135               efree(var_hash);
00136               var_hash = next;
00137        }
00138 }
00139 
00140 /* }}} */
00141 
00142 static char *unserialize_str(const unsigned char **p, size_t *len, size_t maxlen)
00143 {
00144        size_t i, j;
00145        char *str = safe_emalloc(*len, 1, 1);
00146        unsigned char *end = *(unsigned char **)p+maxlen;
00147 
00148        if (end < *p) {
00149               efree(str);
00150               return NULL;
00151        }
00152 
00153        for (i = 0; i < *len; i++) {
00154               if (*p >= end) {
00155                      efree(str);
00156                      return NULL;
00157               }
00158               if (**p != '\\') {
00159                      str[i] = (char)**p;
00160               } else {
00161                      unsigned char ch = 0;
00162 
00163                      for (j = 0; j < 2; j++) {
00164                             (*p)++;
00165                             if (**p >= '0' && **p <= '9') {
00166                                    ch = (ch << 4) + (**p -'0');
00167                             } else if (**p >= 'a' && **p <= 'f') {
00168                                    ch = (ch << 4) + (**p -'a'+10);
00169                             } else if (**p >= 'A' && **p <= 'F') {
00170                                    ch = (ch << 4) + (**p -'A'+10);
00171                             } else {
00172                                    efree(str);
00173                                    return NULL;
00174                             }
00175                      }
00176                      str[i] = (char)ch;
00177               }
00178               (*p)++;
00179        }
00180        str[i] = 0;
00181        *len = i;
00182        return str;
00183 }
00184 
00185 #define YYFILL(n) do { } while (0)
00186 #define YYCTYPE unsigned char
00187 #define YYCURSOR cursor
00188 #define YYLIMIT limit
00189 #define YYMARKER marker
00190 
00191 
00192 
00193 
00194 
00195 
00196 static inline long parse_iv2(const unsigned char *p, const unsigned char **q)
00197 {
00198        char cursor;
00199        long result = 0;
00200        int neg = 0;
00201 
00202        switch (*p) {
00203               case '-':
00204                      neg++;
00205                      /* fall-through */
00206               case '+':
00207                      p++;
00208        }
00209        
00210        while (1) {
00211               cursor = (char)*p;
00212               if (cursor >= '0' && cursor <= '9') {
00213                      result = result * 10 + (size_t)(cursor - (unsigned char)'0');
00214               } else {
00215                      break;
00216               }
00217               p++;
00218        }
00219        if (q) *q = p;
00220        if (neg) return -result;
00221        return result;
00222 }
00223 
00224 static inline long parse_iv(const unsigned char *p)
00225 {
00226        return parse_iv2(p, NULL);
00227 }
00228 
00229 /* no need to check for length - re2c already did */
00230 static inline size_t parse_uiv(const unsigned char *p)
00231 {
00232        unsigned char cursor;
00233        size_t result = 0;
00234 
00235        if (*p == '+') {
00236               p++;
00237        }
00238        
00239        while (1) {
00240               cursor = *p;
00241               if (cursor >= '0' && cursor <= '9') {
00242                      result = result * 10 + (size_t)(cursor - (unsigned char)'0');
00243               } else {
00244                      break;
00245               }
00246               p++;
00247        }
00248        return result;
00249 }
00250 
00251 #define UNSERIALIZE_PARAMETER zval **rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC
00252 #define UNSERIALIZE_PASSTHRU rval, p, max, var_hash TSRMLS_CC
00253 
00254 static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long elements, int objprops)
00255 {
00256        while (elements-- > 0) {
00257               zval *key, *data, **old_data;
00258 
00259               ALLOC_INIT_ZVAL(key);
00260 
00261               if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) {
00262                      zval_dtor(key);
00263                      FREE_ZVAL(key);
00264                      return 0;
00265               }
00266 
00267               if (Z_TYPE_P(key) != IS_LONG && Z_TYPE_P(key) != IS_STRING) {
00268                      zval_dtor(key);
00269                      FREE_ZVAL(key);
00270                      return 0;
00271               }
00272 
00273               ALLOC_INIT_ZVAL(data);
00274 
00275               if (!php_var_unserialize(&data, p, max, var_hash TSRMLS_CC)) {
00276                      zval_dtor(key);
00277                      FREE_ZVAL(key);
00278                      zval_dtor(data);
00279                      FREE_ZVAL(data);
00280                      return 0;
00281               }
00282 
00283               if (!objprops) {
00284                      switch (Z_TYPE_P(key)) {
00285                      case IS_LONG:
00286                             if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)==SUCCESS) {
00287                                    var_push_dtor(var_hash, old_data);
00288                             }
00289                             zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL);
00290                             break;
00291                      case IS_STRING:
00292                             if (zend_symtable_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
00293                                    var_push_dtor(var_hash, old_data);
00294                             }
00295                             zend_symtable_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
00296                             break;
00297                      }
00298               } else {
00299                      /* object properties should include no integers */
00300                      convert_to_string(key);
00301                      zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data,
00302                                    sizeof data, NULL);
00303               }
00304               
00305               zval_dtor(key);
00306               FREE_ZVAL(key);
00307 
00308               if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
00309                      (*p)--;
00310                      return 0;
00311               }
00312        }
00313 
00314        return 1;
00315 }
00316 
00317 static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
00318 {
00319        if (*((*p)++) == '}')
00320               return 1;
00321 
00322 #if SOMETHING_NEW_MIGHT_LEAD_TO_CRASH_ENABLE_IF_YOU_ARE_BRAVE
00323        zval_ptr_dtor(rval);
00324 #endif
00325        return 0;
00326 }
00327 
00328 static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
00329 {
00330        long datalen;
00331 
00332        datalen = parse_iv2((*p) + 2, p);
00333 
00334        (*p) += 2;
00335 
00336        if (datalen < 0 || (*p) + datalen >= max) {
00337               zend_error(E_WARNING, "Insufficient data for unserializing - %ld required, %ld present", datalen, (long)(max - (*p)));
00338               return 0;
00339        }
00340 
00341        if (ce->unserialize == NULL) {
00342               zend_error(E_WARNING, "Class %s has no unserializer", ce->name);
00343               object_init_ex(*rval, ce);
00344        } else if (ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) {
00345               return 0;
00346        }
00347 
00348        (*p) += datalen;
00349 
00350        return finish_nested_data(UNSERIALIZE_PASSTHRU);
00351 }
00352 
00353 static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
00354 {
00355        long elements;
00356        
00357        elements = parse_iv2((*p) + 2, p);
00358 
00359        (*p) += 2;
00360        
00361        object_init_ex(*rval, ce);
00362        return elements;
00363 }
00364 
00365 static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
00366 {
00367        zval *retval_ptr = NULL;
00368        zval fname;
00369 
00370        if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements, 1)) {
00371               return 0;
00372        }
00373 
00374        if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
00375               zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) {
00376               INIT_PZVAL(&fname);
00377               ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0);
00378               call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
00379        }
00380 
00381        if (retval_ptr)
00382               zval_ptr_dtor(&retval_ptr);
00383 
00384        return finish_nested_data(UNSERIALIZE_PASSTHRU);
00385 
00386 }
00387 
00388 PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
00389 {
00390        const unsigned char *cursor, *limit, *marker, *start;
00391        zval **rval_ref;
00392 
00393        limit = cursor = *p;
00394        
00395        if (var_hash && cursor[0] != 'R') {
00396               var_push(var_hash, rval);
00397        }
00398 
00399        start = cursor;
00400 
00401        
00402        
00403 
00404 {
00405        YYCTYPE yych;
00406        static const unsigned char yybm[] = {
00407                 0,   0,   0,   0,   0,   0,   0,   0, 
00408                 0,   0,   0,   0,   0,   0,   0,   0, 
00409                 0,   0,   0,   0,   0,   0,   0,   0, 
00410                 0,   0,   0,   0,   0,   0,   0,   0, 
00411                 0,   0,   0,   0,   0,   0,   0,   0, 
00412                 0,   0,   0,   0,   0,   0,   0,   0, 
00413               128, 128, 128, 128, 128, 128, 128, 128, 
00414               128, 128,   0,   0,   0,   0,   0,   0, 
00415                 0,   0,   0,   0,   0,   0,   0,   0, 
00416                 0,   0,   0,   0,   0,   0,   0,   0, 
00417                 0,   0,   0,   0,   0,   0,   0,   0, 
00418                 0,   0,   0,   0,   0,   0,   0,   0, 
00419                 0,   0,   0,   0,   0,   0,   0,   0, 
00420                 0,   0,   0,   0,   0,   0,   0,   0, 
00421                 0,   0,   0,   0,   0,   0,   0,   0, 
00422                 0,   0,   0,   0,   0,   0,   0,   0, 
00423                 0,   0,   0,   0,   0,   0,   0,   0, 
00424                 0,   0,   0,   0,   0,   0,   0,   0, 
00425                 0,   0,   0,   0,   0,   0,   0,   0, 
00426                 0,   0,   0,   0,   0,   0,   0,   0, 
00427                 0,   0,   0,   0,   0,   0,   0,   0, 
00428                 0,   0,   0,   0,   0,   0,   0,   0, 
00429                 0,   0,   0,   0,   0,   0,   0,   0, 
00430                 0,   0,   0,   0,   0,   0,   0,   0, 
00431                 0,   0,   0,   0,   0,   0,   0,   0, 
00432                 0,   0,   0,   0,   0,   0,   0,   0, 
00433                 0,   0,   0,   0,   0,   0,   0,   0, 
00434                 0,   0,   0,   0,   0,   0,   0,   0, 
00435                 0,   0,   0,   0,   0,   0,   0,   0, 
00436                 0,   0,   0,   0,   0,   0,   0,   0, 
00437                 0,   0,   0,   0,   0,   0,   0,   0, 
00438                 0,   0,   0,   0,   0,   0,   0,   0, 
00439        };
00440 
00441        if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
00442        yych = *YYCURSOR;
00443        switch (yych) {
00444        case 'C':
00445        case 'O':     goto yy13;
00446        case 'N':     goto yy5;
00447        case 'R':     goto yy2;
00448        case 'S':     goto yy10;
00449        case 'a':     goto yy11;
00450        case 'b':     goto yy6;
00451        case 'd':     goto yy8;
00452        case 'i':     goto yy7;
00453        case 'o':     goto yy12;
00454        case 'r':     goto yy4;
00455        case 's':     goto yy9;
00456        case '}':     goto yy14;
00457        default:      goto yy16;
00458        }
00459 yy2:
00460        yych = *(YYMARKER = ++YYCURSOR);
00461        if (yych == ':') goto yy95;
00462 yy3:
00463        { return 0; }
00464 yy4:
00465        yych = *(YYMARKER = ++YYCURSOR);
00466        if (yych == ':') goto yy89;
00467        goto yy3;
00468 yy5:
00469        yych = *++YYCURSOR;
00470        if (yych == ';') goto yy87;
00471        goto yy3;
00472 yy6:
00473        yych = *(YYMARKER = ++YYCURSOR);
00474        if (yych == ':') goto yy83;
00475        goto yy3;
00476 yy7:
00477        yych = *(YYMARKER = ++YYCURSOR);
00478        if (yych == ':') goto yy77;
00479        goto yy3;
00480 yy8:
00481        yych = *(YYMARKER = ++YYCURSOR);
00482        if (yych == ':') goto yy53;
00483        goto yy3;
00484 yy9:
00485        yych = *(YYMARKER = ++YYCURSOR);
00486        if (yych == ':') goto yy46;
00487        goto yy3;
00488 yy10:
00489        yych = *(YYMARKER = ++YYCURSOR);
00490        if (yych == ':') goto yy39;
00491        goto yy3;
00492 yy11:
00493        yych = *(YYMARKER = ++YYCURSOR);
00494        if (yych == ':') goto yy32;
00495        goto yy3;
00496 yy12:
00497        yych = *(YYMARKER = ++YYCURSOR);
00498        if (yych == ':') goto yy25;
00499        goto yy3;
00500 yy13:
00501        yych = *(YYMARKER = ++YYCURSOR);
00502        if (yych == ':') goto yy17;
00503        goto yy3;
00504 yy14:
00505        ++YYCURSOR;
00506        {
00507        /* this is the case where we have less data than planned */
00508        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
00509        return 0; /* not sure if it should be 0 or 1 here? */
00510 }
00511 yy16:
00512        yych = *++YYCURSOR;
00513        goto yy3;
00514 yy17:
00515        yych = *++YYCURSOR;
00516        if (yybm[0+yych] & 128) {
00517               goto yy20;
00518        }
00519        if (yych == '+') goto yy19;
00520 yy18:
00521        YYCURSOR = YYMARKER;
00522        goto yy3;
00523 yy19:
00524        yych = *++YYCURSOR;
00525        if (yybm[0+yych] & 128) {
00526               goto yy20;
00527        }
00528        goto yy18;
00529 yy20:
00530        ++YYCURSOR;
00531        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
00532        yych = *YYCURSOR;
00533        if (yybm[0+yych] & 128) {
00534               goto yy20;
00535        }
00536        if (yych != ':') goto yy18;
00537        yych = *++YYCURSOR;
00538        if (yych != '"') goto yy18;
00539        ++YYCURSOR;
00540        {
00541        size_t len, len2, len3, maxlen;
00542        long elements;
00543        char *class_name;
00544        zend_class_entry *ce;
00545        zend_class_entry **pce;
00546        int incomplete_class = 0;
00547 
00548        int custom_object = 0;
00549 
00550        zval *user_func;
00551        zval *retval_ptr;
00552        zval **args[1];
00553        zval *arg_func_name;
00554 
00555        if (*start == 'C') {
00556               custom_object = 1;
00557        }
00558        
00559        INIT_PZVAL(*rval);
00560        len2 = len = parse_uiv(start + 2);
00561        maxlen = max - YYCURSOR;
00562        if (maxlen < len || len == 0) {
00563               *p = start + 2;
00564               return 0;
00565        }
00566 
00567        class_name = (char*)YYCURSOR;
00568 
00569        YYCURSOR += len;
00570 
00571        if (*(YYCURSOR) != '"') {
00572               *p = YYCURSOR;
00573               return 0;
00574        }
00575        if (*(YYCURSOR+1) != ':') {
00576               *p = YYCURSOR+1;
00577               return 0;
00578        }
00579 
00580        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\\");
00581        if (len3 != len)
00582        {
00583               *p = YYCURSOR + len3 - len;
00584               return 0;
00585        }
00586 
00587        class_name = estrndup(class_name, len);
00588 
00589        do {
00590               /* Try to find class directly */
00591               if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
00592                      ce = *pce;
00593                      break;
00594               }
00595               
00596               /* Check for unserialize callback */
00597               if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
00598                      incomplete_class = 1;
00599                      ce = PHP_IC_ENTRY;
00600                      break;
00601               }
00602               
00603               /* Call unserialize callback */
00604               MAKE_STD_ZVAL(user_func);
00605               ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
00606               args[0] = &arg_func_name;
00607               MAKE_STD_ZVAL(arg_func_name);
00608               ZVAL_STRING(arg_func_name, class_name, 1);
00609               if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
00610                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
00611                      incomplete_class = 1;
00612                      ce = PHP_IC_ENTRY;
00613                      zval_ptr_dtor(&user_func);
00614                      zval_ptr_dtor(&arg_func_name);
00615                      break;
00616               }
00617               if (retval_ptr) {
00618                      zval_ptr_dtor(&retval_ptr);
00619               }
00620               
00621               /* The callback function may have defined the class */
00622               if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
00623                      ce = *pce;
00624               } else {
00625                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val);
00626                      incomplete_class = 1;
00627                      ce = PHP_IC_ENTRY;
00628               }
00629 
00630               zval_ptr_dtor(&user_func);
00631               zval_ptr_dtor(&arg_func_name);
00632               break;
00633        } while (1);
00634 
00635        *p = YYCURSOR;
00636 
00637        if (custom_object) {
00638               int ret = object_custom(UNSERIALIZE_PASSTHRU, ce);
00639 
00640               if (ret && incomplete_class) {
00641                      php_store_class_name(*rval, class_name, len2);
00642               }
00643               efree(class_name);
00644               return ret;
00645        }
00646        
00647        elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
00648 
00649        if (incomplete_class) {
00650               php_store_class_name(*rval, class_name, len2);
00651        }
00652        efree(class_name);
00653 
00654        return object_common2(UNSERIALIZE_PASSTHRU, elements);
00655 }
00656 yy25:
00657        yych = *++YYCURSOR;
00658        if (yych <= ',') {
00659               if (yych != '+') goto yy18;
00660        } else {
00661               if (yych <= '-') goto yy26;
00662               if (yych <= '/') goto yy18;
00663               if (yych <= '9') goto yy27;
00664               goto yy18;
00665        }
00666 yy26:
00667        yych = *++YYCURSOR;
00668        if (yych <= '/') goto yy18;
00669        if (yych >= ':') goto yy18;
00670 yy27:
00671        ++YYCURSOR;
00672        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
00673        yych = *YYCURSOR;
00674        if (yych <= '/') goto yy18;
00675        if (yych <= '9') goto yy27;
00676        if (yych >= ';') goto yy18;
00677        yych = *++YYCURSOR;
00678        if (yych != '"') goto yy18;
00679        ++YYCURSOR;
00680        {
00681 
00682        INIT_PZVAL(*rval);
00683        
00684        return object_common2(UNSERIALIZE_PASSTHRU,
00685                      object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
00686 }
00687 yy32:
00688        yych = *++YYCURSOR;
00689        if (yych == '+') goto yy33;
00690        if (yych <= '/') goto yy18;
00691        if (yych <= '9') goto yy34;
00692        goto yy18;
00693 yy33:
00694        yych = *++YYCURSOR;
00695        if (yych <= '/') goto yy18;
00696        if (yych >= ':') goto yy18;
00697 yy34:
00698        ++YYCURSOR;
00699        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
00700        yych = *YYCURSOR;
00701        if (yych <= '/') goto yy18;
00702        if (yych <= '9') goto yy34;
00703        if (yych >= ';') goto yy18;
00704        yych = *++YYCURSOR;
00705        if (yych != '{') goto yy18;
00706        ++YYCURSOR;
00707        {
00708        long elements = parse_iv(start + 2);
00709        /* use iv() not uiv() in order to check data range */
00710        *p = YYCURSOR;
00711 
00712        if (elements < 0) {
00713               return 0;
00714        }
00715 
00716        INIT_PZVAL(*rval);
00717 
00718        array_init_size(*rval, elements);
00719 
00720        if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) {
00721               return 0;
00722        }
00723 
00724        return finish_nested_data(UNSERIALIZE_PASSTHRU);
00725 }
00726 yy39:
00727        yych = *++YYCURSOR;
00728        if (yych == '+') goto yy40;
00729        if (yych <= '/') goto yy18;
00730        if (yych <= '9') goto yy41;
00731        goto yy18;
00732 yy40:
00733        yych = *++YYCURSOR;
00734        if (yych <= '/') goto yy18;
00735        if (yych >= ':') goto yy18;
00736 yy41:
00737        ++YYCURSOR;
00738        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
00739        yych = *YYCURSOR;
00740        if (yych <= '/') goto yy18;
00741        if (yych <= '9') goto yy41;
00742        if (yych >= ';') goto yy18;
00743        yych = *++YYCURSOR;
00744        if (yych != '"') goto yy18;
00745        ++YYCURSOR;
00746        {
00747        size_t len, maxlen;
00748        char *str;
00749 
00750        len = parse_uiv(start + 2);
00751        maxlen = max - YYCURSOR;
00752        if (maxlen < len) {
00753               *p = start + 2;
00754               return 0;
00755        }
00756 
00757        if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) {
00758               return 0;
00759        }
00760 
00761        if (*(YYCURSOR) != '"') {
00762               efree(str);
00763               *p = YYCURSOR;
00764               return 0;
00765        }
00766 
00767        YYCURSOR += 2;
00768        *p = YYCURSOR;
00769 
00770        INIT_PZVAL(*rval);
00771        ZVAL_STRINGL(*rval, str, len, 0);
00772        return 1;
00773 }
00774 yy46:
00775        yych = *++YYCURSOR;
00776        if (yych == '+') goto yy47;
00777        if (yych <= '/') goto yy18;
00778        if (yych <= '9') goto yy48;
00779        goto yy18;
00780 yy47:
00781        yych = *++YYCURSOR;
00782        if (yych <= '/') goto yy18;
00783        if (yych >= ':') goto yy18;
00784 yy48:
00785        ++YYCURSOR;
00786        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
00787        yych = *YYCURSOR;
00788        if (yych <= '/') goto yy18;
00789        if (yych <= '9') goto yy48;
00790        if (yych >= ';') goto yy18;
00791        yych = *++YYCURSOR;
00792        if (yych != '"') goto yy18;
00793        ++YYCURSOR;
00794        {
00795        size_t len, maxlen;
00796        char *str;
00797 
00798        len = parse_uiv(start + 2);
00799        maxlen = max - YYCURSOR;
00800        if (maxlen < len) {
00801               *p = start + 2;
00802               return 0;
00803        }
00804 
00805        str = (char*)YYCURSOR;
00806 
00807        YYCURSOR += len;
00808 
00809        if (*(YYCURSOR) != '"') {
00810               *p = YYCURSOR;
00811               return 0;
00812        }
00813 
00814        YYCURSOR += 2;
00815        *p = YYCURSOR;
00816 
00817        INIT_PZVAL(*rval);
00818        ZVAL_STRINGL(*rval, str, len, 1);
00819        return 1;
00820 }
00821 yy53:
00822        yych = *++YYCURSOR;
00823        if (yych <= '/') {
00824               if (yych <= ',') {
00825                      if (yych == '+') goto yy57;
00826                      goto yy18;
00827               } else {
00828                      if (yych <= '-') goto yy55;
00829                      if (yych <= '.') goto yy60;
00830                      goto yy18;
00831               }
00832        } else {
00833               if (yych <= 'I') {
00834                      if (yych <= '9') goto yy58;
00835                      if (yych <= 'H') goto yy18;
00836                      goto yy56;
00837               } else {
00838                      if (yych != 'N') goto yy18;
00839               }
00840        }
00841        yych = *++YYCURSOR;
00842        if (yych == 'A') goto yy76;
00843        goto yy18;
00844 yy55:
00845        yych = *++YYCURSOR;
00846        if (yych <= '/') {
00847               if (yych == '.') goto yy60;
00848               goto yy18;
00849        } else {
00850               if (yych <= '9') goto yy58;
00851               if (yych != 'I') goto yy18;
00852        }
00853 yy56:
00854        yych = *++YYCURSOR;
00855        if (yych == 'N') goto yy72;
00856        goto yy18;
00857 yy57:
00858        yych = *++YYCURSOR;
00859        if (yych == '.') goto yy60;
00860        if (yych <= '/') goto yy18;
00861        if (yych >= ':') goto yy18;
00862 yy58:
00863        ++YYCURSOR;
00864        if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
00865        yych = *YYCURSOR;
00866        if (yych <= ':') {
00867               if (yych <= '.') {
00868                      if (yych <= '-') goto yy18;
00869                      goto yy70;
00870               } else {
00871                      if (yych <= '/') goto yy18;
00872                      if (yych <= '9') goto yy58;
00873                      goto yy18;
00874               }
00875        } else {
00876               if (yych <= 'E') {
00877                      if (yych <= ';') goto yy63;
00878                      if (yych <= 'D') goto yy18;
00879                      goto yy65;
00880               } else {
00881                      if (yych == 'e') goto yy65;
00882                      goto yy18;
00883               }
00884        }
00885 yy60:
00886        yych = *++YYCURSOR;
00887        if (yych <= '/') goto yy18;
00888        if (yych >= ':') goto yy18;
00889 yy61:
00890        ++YYCURSOR;
00891        if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
00892        yych = *YYCURSOR;
00893        if (yych <= ';') {
00894               if (yych <= '/') goto yy18;
00895               if (yych <= '9') goto yy61;
00896               if (yych <= ':') goto yy18;
00897        } else {
00898               if (yych <= 'E') {
00899                      if (yych <= 'D') goto yy18;
00900                      goto yy65;
00901               } else {
00902                      if (yych == 'e') goto yy65;
00903                      goto yy18;
00904               }
00905        }
00906 yy63:
00907        ++YYCURSOR;
00908        {
00909 #if SIZEOF_LONG == 4
00910 use_double:
00911 #endif
00912        *p = YYCURSOR;
00913        INIT_PZVAL(*rval);
00914        ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
00915        return 1;
00916 }
00917 yy65:
00918        yych = *++YYCURSOR;
00919        if (yych <= ',') {
00920               if (yych != '+') goto yy18;
00921        } else {
00922               if (yych <= '-') goto yy66;
00923               if (yych <= '/') goto yy18;
00924               if (yych <= '9') goto yy67;
00925               goto yy18;
00926        }
00927 yy66:
00928        yych = *++YYCURSOR;
00929        if (yych <= ',') {
00930               if (yych == '+') goto yy69;
00931               goto yy18;
00932        } else {
00933               if (yych <= '-') goto yy69;
00934               if (yych <= '/') goto yy18;
00935               if (yych >= ':') goto yy18;
00936        }
00937 yy67:
00938        ++YYCURSOR;
00939        if (YYLIMIT <= YYCURSOR) YYFILL(1);
00940        yych = *YYCURSOR;
00941        if (yych <= '/') goto yy18;
00942        if (yych <= '9') goto yy67;
00943        if (yych == ';') goto yy63;
00944        goto yy18;
00945 yy69:
00946        yych = *++YYCURSOR;
00947        if (yych <= '/') goto yy18;
00948        if (yych <= '9') goto yy67;
00949        goto yy18;
00950 yy70:
00951        ++YYCURSOR;
00952        if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
00953        yych = *YYCURSOR;
00954        if (yych <= ';') {
00955               if (yych <= '/') goto yy18;
00956               if (yych <= '9') goto yy70;
00957               if (yych <= ':') goto yy18;
00958               goto yy63;
00959        } else {
00960               if (yych <= 'E') {
00961                      if (yych <= 'D') goto yy18;
00962                      goto yy65;
00963               } else {
00964                      if (yych == 'e') goto yy65;
00965                      goto yy18;
00966               }
00967        }
00968 yy72:
00969        yych = *++YYCURSOR;
00970        if (yych != 'F') goto yy18;
00971 yy73:
00972        yych = *++YYCURSOR;
00973        if (yych != ';') goto yy18;
00974        ++YYCURSOR;
00975        {
00976        *p = YYCURSOR;
00977        INIT_PZVAL(*rval);
00978 
00979        if (!strncmp(start + 2, "NAN", 3)) {
00980               ZVAL_DOUBLE(*rval, php_get_nan());
00981        } else if (!strncmp(start + 2, "INF", 3)) {
00982               ZVAL_DOUBLE(*rval, php_get_inf());
00983        } else if (!strncmp(start + 2, "-INF", 4)) {
00984               ZVAL_DOUBLE(*rval, -php_get_inf());
00985        }
00986 
00987        return 1;
00988 }
00989 yy76:
00990        yych = *++YYCURSOR;
00991        if (yych == 'N') goto yy73;
00992        goto yy18;
00993 yy77:
00994        yych = *++YYCURSOR;
00995        if (yych <= ',') {
00996               if (yych != '+') goto yy18;
00997        } else {
00998               if (yych <= '-') goto yy78;
00999               if (yych <= '/') goto yy18;
01000               if (yych <= '9') goto yy79;
01001               goto yy18;
01002        }
01003 yy78:
01004        yych = *++YYCURSOR;
01005        if (yych <= '/') goto yy18;
01006        if (yych >= ':') goto yy18;
01007 yy79:
01008        ++YYCURSOR;
01009        if (YYLIMIT <= YYCURSOR) YYFILL(1);
01010        yych = *YYCURSOR;
01011        if (yych <= '/') goto yy18;
01012        if (yych <= '9') goto yy79;
01013        if (yych != ';') goto yy18;
01014        ++YYCURSOR;
01015        {
01016 #if SIZEOF_LONG == 4
01017        int digits = YYCURSOR - start - 3;
01018 
01019        if (start[2] == '-' || start[2] == '+') {
01020               digits--;
01021        }
01022 
01023        /* Use double for large long values that were serialized on a 64-bit system */
01024        if (digits >= MAX_LENGTH_OF_LONG - 1) {
01025               if (digits == MAX_LENGTH_OF_LONG - 1) {
01026                      int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
01027 
01028                      if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
01029                             goto use_double;
01030                      }
01031               } else {
01032                      goto use_double;
01033               }
01034        }
01035 #endif
01036        *p = YYCURSOR;
01037        INIT_PZVAL(*rval);
01038        ZVAL_LONG(*rval, parse_iv(start + 2));
01039        return 1;
01040 }
01041 yy83:
01042        yych = *++YYCURSOR;
01043        if (yych <= '/') goto yy18;
01044        if (yych >= '2') goto yy18;
01045        yych = *++YYCURSOR;
01046        if (yych != ';') goto yy18;
01047        ++YYCURSOR;
01048        {
01049        *p = YYCURSOR;
01050        INIT_PZVAL(*rval);
01051        ZVAL_BOOL(*rval, parse_iv(start + 2));
01052        return 1;
01053 }
01054 yy87:
01055        ++YYCURSOR;
01056        {
01057        *p = YYCURSOR;
01058        INIT_PZVAL(*rval);
01059        ZVAL_NULL(*rval);
01060        return 1;
01061 }
01062 yy89:
01063        yych = *++YYCURSOR;
01064        if (yych <= ',') {
01065               if (yych != '+') goto yy18;
01066        } else {
01067               if (yych <= '-') goto yy90;
01068               if (yych <= '/') goto yy18;
01069               if (yych <= '9') goto yy91;
01070               goto yy18;
01071        }
01072 yy90:
01073        yych = *++YYCURSOR;
01074        if (yych <= '/') goto yy18;
01075        if (yych >= ':') goto yy18;
01076 yy91:
01077        ++YYCURSOR;
01078        if (YYLIMIT <= YYCURSOR) YYFILL(1);
01079        yych = *YYCURSOR;
01080        if (yych <= '/') goto yy18;
01081        if (yych <= '9') goto yy91;
01082        if (yych != ';') goto yy18;
01083        ++YYCURSOR;
01084        {
01085        long id;
01086 
01087        *p = YYCURSOR;
01088        if (!var_hash) return 0;
01089 
01090        id = parse_iv(start + 2) - 1;
01091        if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
01092               return 0;
01093        }
01094 
01095        if (*rval == *rval_ref) return 0;
01096 
01097        if (*rval != NULL) {
01098               zval_ptr_dtor(rval);
01099        }
01100        *rval = *rval_ref;
01101        Z_ADDREF_PP(rval);
01102        Z_UNSET_ISREF_PP(rval);
01103        
01104        return 1;
01105 }
01106 yy95:
01107        yych = *++YYCURSOR;
01108        if (yych <= ',') {
01109               if (yych != '+') goto yy18;
01110        } else {
01111               if (yych <= '-') goto yy96;
01112               if (yych <= '/') goto yy18;
01113               if (yych <= '9') goto yy97;
01114               goto yy18;
01115        }
01116 yy96:
01117        yych = *++YYCURSOR;
01118        if (yych <= '/') goto yy18;
01119        if (yych >= ':') goto yy18;
01120 yy97:
01121        ++YYCURSOR;
01122        if (YYLIMIT <= YYCURSOR) YYFILL(1);
01123        yych = *YYCURSOR;
01124        if (yych <= '/') goto yy18;
01125        if (yych <= '9') goto yy97;
01126        if (yych != ';') goto yy18;
01127        ++YYCURSOR;
01128        {
01129        long id;
01130 
01131        *p = YYCURSOR;
01132        if (!var_hash) return 0;
01133 
01134        id = parse_iv(start + 2) - 1;
01135        if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
01136               return 0;
01137        }
01138 
01139        if (*rval != NULL) {
01140               zval_ptr_dtor(rval);
01141        }
01142        *rval = *rval_ref;
01143        Z_ADDREF_PP(rval);
01144        Z_SET_ISREF_PP(rval);
01145        
01146        return 1;
01147 }
01148 }
01149 
01150 
01151        return 0;
01152 }