LTP GCOV extension - code coverage report
Current view: directory - home/mike/build/php-5.2-gcov/lcov_data/ext/standard - var_unserializer.re
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 337
Code covered: 1.8 % Executed lines: 6
Legend: not executed executed

       1                 : /*
       2                 :   +----------------------------------------------------------------------+
       3                 :   | PHP Version 5                                                        |
       4                 :   +----------------------------------------------------------------------+
       5                 :   | Copyright (c) 1997-2006 The PHP Group                                |
       6                 :   +----------------------------------------------------------------------+
       7                 :   | This source file is subject to version 3.01 of the PHP license,      |
       8                 :   | that is bundled with this package in the file LICENSE, and is        |
       9                 :   | available through the world-wide-web at the following url:           |
      10                 :   | http://www.php.net/license/3_01.txt                                  |
      11                 :   | If you did not receive a copy of the PHP license and are unable to   |
      12                 :   | obtain it through the world-wide-web, please send a note to          |
      13                 :   | license@php.net so we can mail you a copy immediately.               |
      14                 :   +----------------------------------------------------------------------+
      15                 :   | Author: Sascha Schumann <sascha@schumann.cx>                         |
      16                 :   +----------------------------------------------------------------------+
      17                 : */
      18                 : 
      19                 : /* $Id: var_unserializer.re,v 1.52.2.2.2.3 2007/03/27 09:29:10 tony2001 Exp $ */
      20                 : 
      21                 : #include "php.h"
      22                 : #include "ext/standard/php_var.h"
      23                 : #include "php_incomplete_class.h"
      24                 : 
      25                 : /* {{{ reference-handling for unserializer: var_* */
      26                 : #define VAR_ENTRIES_MAX 1024
      27                 : 
      28                 : typedef struct {
      29                 :         zval *data[VAR_ENTRIES_MAX];
      30                 :         long used_slots;
      31                 :         void *next;
      32                 : } var_entries;
      33                 : 
      34                 : static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval)
      35               0 : {
      36               0 :         var_entries *var_hash = var_hashx->first, *prev = NULL;
      37                 : 
      38               0 :         while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
      39               0 :                 prev = var_hash;
      40               0 :                 var_hash = var_hash->next;
      41                 :         }
      42                 : 
      43               0 :         if (!var_hash) {
      44               0 :                 var_hash = emalloc(sizeof(var_entries));
      45               0 :                 var_hash->used_slots = 0;
      46               0 :                 var_hash->next = 0;
      47                 : 
      48               0 :                 if (!var_hashx->first)
      49               0 :                         var_hashx->first = var_hash;
      50                 :                 else
      51               0 :                         prev->next = var_hash;
      52                 :         }
      53                 : 
      54               0 :         var_hash->data[var_hash->used_slots++] = *rval;
      55               0 : }
      56                 : 
      57                 : static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
      58               0 : {
      59               0 :         var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
      60                 : 
      61               0 :         while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
      62               0 :                 prev = var_hash;
      63               0 :                 var_hash = var_hash->next;
      64                 :         }
      65                 : 
      66               0 :         if (!var_hash) {
      67               0 :                 var_hash = emalloc(sizeof(var_entries));
      68               0 :                 var_hash->used_slots = 0;
      69               0 :                 var_hash->next = 0;
      70                 : 
      71               0 :                 if (!var_hashx->first_dtor)
      72               0 :                         var_hashx->first_dtor = var_hash;
      73                 :                 else
      74               0 :                         prev->next = var_hash;
      75                 :         }
      76                 : 
      77               0 :         (*rval)->refcount++;
      78               0 :         var_hash->data[var_hash->used_slots++] = *rval;
      79               0 : }
      80                 : 
      81                 : PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval)
      82               0 : {
      83                 :         long i;
      84               0 :         var_entries *var_hash = var_hashx->first;
      85                 :         
      86               0 :         while (var_hash) {
      87               0 :                 for (i = 0; i < var_hash->used_slots; i++) {
      88               0 :                         if (var_hash->data[i] == ozval) {
      89               0 :                                 var_hash->data[i] = *nzval;
      90                 :                                 /* do not break here */
      91                 :                         }
      92                 :                 }
      93               0 :                 var_hash = var_hash->next;
      94                 :         }
      95               0 : }
      96                 : 
      97                 : static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store)
      98               0 : {
      99               0 :         var_entries *var_hash = var_hashx->first;
     100                 :         
     101               0 :         while (id >= VAR_ENTRIES_MAX && var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
     102               0 :                 var_hash = var_hash->next;
     103               0 :                 id -= VAR_ENTRIES_MAX;
     104                 :         }
     105                 : 
     106               0 :         if (!var_hash) return !SUCCESS;
     107                 : 
     108               0 :         if (id < 0 || id >= var_hash->used_slots) return !SUCCESS;
     109                 : 
     110               0 :         *store = &var_hash->data[id];
     111                 : 
     112               0 :         return SUCCESS;
     113                 : }
     114                 : 
     115                 : PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
     116               1 : {
     117                 :         void *next;
     118                 :         long i;
     119               1 :         var_entries *var_hash = var_hashx->first;
     120                 :         
     121               2 :         while (var_hash) {
     122               0 :                 next = var_hash->next;
     123               0 :                 efree(var_hash);
     124               0 :                 var_hash = next;
     125                 :         }
     126                 : 
     127               1 :         var_hash = var_hashx->first_dtor;
     128                 :         
     129               2 :         while (var_hash) {
     130               0 :                 for (i = 0; i < var_hash->used_slots; i++) {
     131               0 :                         zval_ptr_dtor(&var_hash->data[i]);
     132                 :                 }
     133               0 :                 next = var_hash->next;
     134               0 :                 efree(var_hash);
     135               0 :                 var_hash = next;
     136                 :         }
     137               1 : }
     138                 : 
     139                 : /* }}} */
     140                 : 
     141                 : static char *unserialize_str(const unsigned char **p, size_t *len)
     142               0 : {
     143                 :         size_t i, j;
     144               0 :         char *str = safe_emalloc(*len, 1, 1);
     145               0 :         unsigned char *end = *(unsigned char **)p+*len;
     146                 : 
     147               0 :         if(end < *p) {
     148               0 :                 efree(str);
     149               0 :                 return NULL;
     150                 :         }
     151                 : 
     152               0 :         for (i = 0; i < *len && *p < end; i++) {
     153               0 :                 if (**p != '\\') {
     154               0 :                         str[i] = (char)**p;
     155                 :                 } else {
     156               0 :                         unsigned char ch = 0;
     157                 : 
     158               0 :                         for (j = 0; j < 2; j++) {
     159               0 :                                 (*p)++;
     160               0 :                                 if (**p >= '0' && **p <= '9') {
     161               0 :                                         ch = (ch << 4) + (**p -'0');
     162               0 :                                 } else if (**p >= 'a' && **p <= 'f') {
     163               0 :                                         ch = (ch << 4) + (**p -'a'+10);
     164               0 :                                 } else if (**p >= 'A' && **p <= 'F') {
     165               0 :                                         ch = (ch << 4) + (**p -'A'+10);
     166                 :                                 } else {
     167               0 :                                         efree(str);
     168               0 :                                         return NULL;
     169                 :                                 }
     170                 :                         }
     171               0 :                         str[i] = (char)ch;
     172                 :                 }
     173               0 :                 (*p)++;
     174                 :         }
     175               0 :         str[i] = 0;
     176               0 :         *len = i;
     177               0 :         return str;
     178                 : }
     179                 : 
     180                 : #define YYFILL(n) do { } while (0)
     181                 : #define YYCTYPE unsigned char
     182                 : #define YYCURSOR cursor
     183                 : #define YYLIMIT limit
     184                 : #define YYMARKER marker
     185                 : 
     186                 : 
     187                 : /*!re2c
     188                 : uiv = [+]? [0-9]+;
     189                 : iv = [+-]? [0-9]+;
     190                 : nv = [+-]? ([0-9]* "." [0-9]+|[0-9]+ "." [0-9]*);
     191                 : nvexp = (iv | nv) [eE] [+-]? iv;
     192                 : any = [\000-\377];
     193                 : object = [OC];
     194                 : */
     195                 : 
     196                 : 
     197                 : 
     198                 : static inline long parse_iv2(const unsigned char *p, const unsigned char **q)
     199               0 : {
     200                 :         char cursor;
     201               0 :         long result = 0;
     202               0 :         int neg = 0;
     203                 : 
     204               0 :         switch (*p) {
     205                 :                 case '-':
     206               0 :                         neg++;
     207                 :                         /* fall-through */
     208                 :                 case '+':
     209               0 :                         p++;
     210                 :         }
     211                 :         
     212                 :         while (1) {
     213               0 :                 cursor = (char)*p;
     214               0 :                 if (cursor >= '0' && cursor <= '9') {
     215               0 :                         result = result * 10 + cursor - '0';
     216                 :                 } else {
     217                 :                         break;
     218                 :                 }
     219               0 :                 p++;
     220               0 :         }
     221               0 :         if (q) *q = p;
     222               0 :         if (neg) return -result;
     223               0 :         return result;
     224                 : }
     225                 : 
     226                 : static inline long parse_iv(const unsigned char *p)
     227               0 : {
     228               0 :         return parse_iv2(p, NULL);
     229                 : }
     230                 : 
     231                 : /* no need to check for length - re2c already did */
     232                 : static inline size_t parse_uiv(const unsigned char *p)
     233               0 : {
     234                 :         unsigned char cursor;
     235               0 :         size_t result = 0;
     236                 : 
     237               0 :         if (*p == '+') {
     238               0 :                 p++;
     239                 :         }
     240                 :         
     241                 :         while (1) {
     242               0 :                 cursor = *p;
     243               0 :                 if (cursor >= '0' && cursor <= '9') {
     244               0 :                         result = result * 10 + (size_t)(cursor - (unsigned char)'0');
     245                 :                 } else {
     246                 :                         break;
     247                 :                 }
     248               0 :                 p++;
     249               0 :         }
     250               0 :         return result;
     251                 : }
     252                 : 
     253                 : #define UNSERIALIZE_PARAMETER zval **rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC
     254                 : #define UNSERIALIZE_PASSTHRU rval, p, max, var_hash TSRMLS_CC
     255                 : 
     256                 : static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long elements)
     257               0 : {
     258               0 :         while (elements-- > 0) {
     259                 :                 zval *key, *data, **old_data;
     260                 : 
     261               0 :                 ALLOC_INIT_ZVAL(key);
     262                 : 
     263               0 :                 if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) {
     264               0 :                         zval_dtor(key);
     265               0 :                         FREE_ZVAL(key);
     266               0 :                         return 0;
     267                 :                 }
     268                 : 
     269               0 :                 if (Z_TYPE_P(key) != IS_LONG && Z_TYPE_P(key) != IS_STRING) {
     270               0 :                         zval_dtor(key);
     271               0 :                         FREE_ZVAL(key);
     272               0 :                         return 0;
     273                 :                 }
     274                 : 
     275               0 :                 ALLOC_INIT_ZVAL(data);
     276                 : 
     277               0 :                 if (!php_var_unserialize(&data, p, max, var_hash TSRMLS_CC)) {
     278               0 :                         zval_dtor(key);
     279               0 :                         FREE_ZVAL(key);
     280               0 :                         zval_dtor(data);
     281               0 :                         FREE_ZVAL(data);
     282               0 :                         return 0;
     283                 :                 }
     284                 : 
     285               0 :                 switch (Z_TYPE_P(key)) {
     286                 :                         case IS_LONG:
     287               0 :                                 if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)==SUCCESS) {
     288               0 :                                         var_push_dtor(var_hash, old_data);
     289                 :                                 }
     290               0 :                                 zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL);
     291               0 :                                 break;
     292                 :                         case IS_STRING:
     293               0 :                                 if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
     294               0 :                                         var_push_dtor(var_hash, old_data);
     295                 :                                 }
     296               0 :                                 zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
     297                 :                                 break;
     298                 :                 }
     299                 :                 
     300               0 :                 zval_dtor(key);
     301               0 :                 FREE_ZVAL(key);
     302                 : 
     303               0 :                 if (elements && *(*p-1) != ';' &&  *(*p-1) != '}') {
     304               0 :                         (*p)--;
     305               0 :                         return 0;
     306                 :                 }
     307                 :         }
     308                 : 
     309               0 :         return 1;
     310                 : }
     311                 : 
     312                 : static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
     313               0 : {
     314               0 :         if (*((*p)++) == '}') 
     315               0 :                 return 1;
     316                 : 
     317                 : #if SOMETHING_NEW_MIGHT_LEAD_TO_CRASH_ENABLE_IF_YOU_ARE_BRAVE
     318                 :         zval_ptr_dtor(rval);
     319                 : #endif
     320               0 :         return 0;
     321                 : }
     322                 : 
     323                 : static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
     324               0 : {
     325                 :         long datalen;
     326                 : 
     327               0 :         if(ce->unserialize == NULL) {
     328               0 :                 zend_error(E_WARNING, "Class %s has no unserializer", ce->name);
     329               0 :                 return 0;
     330                 :         }
     331                 : 
     332               0 :         datalen = parse_iv2((*p) + 2, p);
     333                 : 
     334               0 :         (*p) += 2;
     335                 : 
     336               0 :         if(datalen < 0 || (*p) + datalen >= max) {
     337               0 :                 zend_error(E_WARNING, "Insufficient data for unserializing - %ld required, %d present", datalen, max - (*p));
     338               0 :                 return 0;
     339                 :         }
     340                 : 
     341               0 :         if(ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) {
     342               0 :                 return 0;
     343                 :         }
     344                 : 
     345               0 :         (*p) += datalen;
     346                 : 
     347               0 :         return finish_nested_data(UNSERIALIZE_PASSTHRU);
     348                 : }
     349                 : 
     350                 : static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
     351               0 : {
     352                 :         long elements;
     353                 :         
     354               0 :         elements = parse_iv2((*p) + 2, p);
     355                 : 
     356               0 :         (*p) += 2;
     357                 :         
     358               0 :         object_init_ex(*rval, ce);
     359               0 :         return elements;
     360                 : }
     361                 : 
     362                 : static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
     363               0 : {
     364               0 :         zval *retval_ptr = NULL;
     365                 :         zval fname;
     366                 : 
     367               0 :         if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements)) {
     368               0 :                 return 0;
     369                 :         }
     370                 : 
     371               0 :         if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
     372                 :             zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) {
     373               0 :                 INIT_PZVAL(&fname);
     374               0 :                 ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0);
     375               0 :                 call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
     376                 :         }
     377                 : 
     378               0 :         if (retval_ptr)
     379               0 :                 zval_ptr_dtor(&retval_ptr);
     380                 : 
     381               0 :         return finish_nested_data(UNSERIALIZE_PASSTHRU);
     382                 : 
     383                 : }
     384                 : 
     385                 : PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
     386               0 : {
     387                 :         const unsigned char *cursor, *limit, *marker, *start;
     388                 :         zval **rval_ref;
     389                 : 
     390               0 :         limit = cursor = *p;
     391                 :         
     392               0 :         if (var_hash && cursor[0] != 'R') {
     393               0 :                 var_push(var_hash, rval);
     394                 :         }
     395                 : 
     396               0 :         start = cursor;
     397                 : 
     398                 :         
     399                 :         
     400                 : /*!re2c
     401                 : 
     402                 : "R:" iv ";"         {
     403                 :         long id;
     404                 : 
     405               0 :         *p = YYCURSOR;
     406               0 :         if (!var_hash) return 0;
     407                 : 
     408               0 :         id = parse_iv(start + 2) - 1;
     409               0 :         if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
     410               0 :                 return 0;
     411                 :         }
     412                 : 
     413               0 :         if (*rval != NULL) {
     414               0 :                 zval_ptr_dtor(rval);
     415                 :         }
     416               0 :         *rval = *rval_ref;
     417               0 :         (*rval)->refcount++;
     418               0 :         (*rval)->is_ref = 1;
     419                 :         
     420               0 :         return 1;
     421                 : }
     422                 : 
     423                 : "r:" iv ";"         {
     424                 :         long id;
     425                 : 
     426               0 :         *p = YYCURSOR;
     427               0 :         if (!var_hash) return 0;
     428                 : 
     429               0 :         id = parse_iv(start + 2) - 1;
     430               0 :         if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
     431               0 :                 return 0;
     432                 :         }
     433                 : 
     434               0 :         if (*rval == *rval_ref) return 0;
     435                 : 
     436               0 :         if (*rval != NULL) {
     437               0 :                 zval_ptr_dtor(rval);
     438                 :         }
     439               0 :         *rval = *rval_ref;
     440               0 :         (*rval)->refcount++;
     441               0 :         (*rval)->is_ref = 0;
     442                 :         
     443               0 :         return 1;
     444                 : }
     445                 : 
     446                 : "N;"  {
     447               0 :         *p = YYCURSOR;
     448               0 :         INIT_PZVAL(*rval);
     449               0 :         ZVAL_NULL(*rval);
     450               0 :         return 1;
     451                 : }
     452                 : 
     453                 : "b:" [01] ";"       {
     454               0 :         *p = YYCURSOR;
     455               0 :         INIT_PZVAL(*rval);
     456               0 :         ZVAL_BOOL(*rval, parse_iv(start + 2));
     457               0 :         return 1;
     458                 : }
     459                 : 
     460                 : "i:" iv ";" {
     461               0 :         *p = YYCURSOR;
     462               0 :         INIT_PZVAL(*rval);
     463               0 :         ZVAL_LONG(*rval, parse_iv(start + 2));
     464               0 :         return 1;
     465                 : }
     466                 : 
     467                 : "d:" ("NAN" | "-"? "INF") ";" {
     468               0 :         *p = YYCURSOR;
     469               0 :         INIT_PZVAL(*rval);
     470                 : 
     471               0 :         if (!strncmp(start + 2, "NAN", 3)) {
     472               0 :                 ZVAL_DOUBLE(*rval, php_get_nan());
     473               0 :         } else if (!strncmp(start + 2, "INF", 3)) {
     474               0 :                 ZVAL_DOUBLE(*rval, php_get_inf());
     475               0 :         } else if (!strncmp(start + 2, "-INF", 4)) {
     476               0 :                 ZVAL_DOUBLE(*rval, -php_get_inf());
     477                 :         }
     478                 : 
     479               0 :         return 1;
     480                 : }
     481                 : 
     482                 : "d:" (iv | nv | nvexp) ";"  {
     483               0 :         *p = YYCURSOR;
     484               0 :         INIT_PZVAL(*rval);
     485               0 :         ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
     486               0 :         return 1;
     487                 : }
     488                 : 
     489                 : "s:" uiv ":" ["]       {
     490                 :         size_t len, maxlen;
     491                 :         char *str;
     492                 : 
     493               0 :         len = parse_uiv(start + 2);
     494               0 :         maxlen = max - YYCURSOR;
     495               0 :         if (maxlen < len) {
     496               0 :                 *p = start + 2;
     497               0 :                 return 0;
     498                 :         }
     499                 : 
     500               0 :         str = (char*)YYCURSOR;
     501                 : 
     502               0 :         YYCURSOR += len;
     503                 : 
     504               0 :         if (*(YYCURSOR) != '"') {
     505               0 :                 *p = YYCURSOR;
     506               0 :                 return 0;
     507                 :         }
     508                 : 
     509               0 :         YYCURSOR += 2;
     510               0 :         *p = YYCURSOR;
     511                 : 
     512               0 :         INIT_PZVAL(*rval);
     513               0 :         ZVAL_STRINGL(*rval, str, len, 1);
     514               0 :         return 1;
     515                 : }
     516                 : 
     517                 : "S:" uiv ":" ["]       {
     518                 :         size_t len, maxlen;
     519                 :         char *str;
     520                 : 
     521               0 :         len = parse_uiv(start + 2);
     522               0 :         maxlen = max - YYCURSOR;
     523               0 :         if (maxlen < len) {
     524               0 :                 *p = start + 2;
     525               0 :                 return 0;
     526                 :         }
     527                 : 
     528               0 :         if ((str = unserialize_str(&YYCURSOR, &len)) == NULL) {
     529               0 :                 return 0;
     530                 :         }
     531                 : 
     532               0 :         if (*(YYCURSOR) != '"') {
     533               0 :                 efree(str);
     534               0 :                 *p = YYCURSOR;
     535               0 :                 return 0;
     536                 :         }
     537                 : 
     538               0 :         YYCURSOR += 2;
     539               0 :         *p = YYCURSOR;
     540                 : 
     541               0 :         INIT_PZVAL(*rval);
     542               0 :         ZVAL_STRINGL(*rval, str, len, 0);
     543               0 :         return 1;
     544                 : }
     545                 : 
     546                 : "a:" uiv ":" "{" {
     547               0 :         long elements = parse_iv(start + 2);
     548                 :         /* use iv() not uiv() in order to check data range */
     549               0 :         *p = YYCURSOR;
     550                 : 
     551               0 :         if (elements < 0) {
     552               0 :                 return 0;
     553                 :         }
     554                 : 
     555               0 :         INIT_PZVAL(*rval);
     556               0 :         Z_TYPE_PP(rval) = IS_ARRAY;
     557               0 :         ALLOC_HASHTABLE(Z_ARRVAL_PP(rval));
     558                 : 
     559               0 :         zend_hash_init(Z_ARRVAL_PP(rval), elements + 1, NULL, ZVAL_PTR_DTOR, 0);
     560                 : 
     561               0 :         if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements)) {
     562               0 :                 return 0;
     563                 :         }
     564                 : 
     565               0 :         return finish_nested_data(UNSERIALIZE_PASSTHRU);
     566                 : }
     567                 : 
     568                 : "o:" iv ":" ["] {
     569                 : 
     570               0 :         INIT_PZVAL(*rval);
     571                 :         
     572               0 :         return object_common2(UNSERIALIZE_PASSTHRU,
     573                 :                         object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
     574                 : }
     575                 : 
     576                 : object ":" uiv ":" ["] {
     577                 :         size_t len, len2, len3, maxlen;
     578                 :         long elements;
     579                 :         char *class_name;
     580                 :         zend_class_entry *ce;
     581                 :         zend_class_entry **pce;
     582               0 :         int incomplete_class = 0;
     583                 : 
     584               0 :         int custom_object = 0;
     585                 : 
     586                 :         zval *user_func;
     587                 :         zval *retval_ptr;
     588                 :         zval **args[1];
     589                 :         zval *arg_func_name;
     590                 : 
     591               0 :         if(*start == 'C') {
     592               0 :                 custom_object = 1;
     593                 :         }
     594                 :         
     595               0 :         INIT_PZVAL(*rval);
     596               0 :         len2 = len = parse_uiv(start + 2);
     597               0 :         maxlen = max - YYCURSOR;
     598               0 :         if (maxlen < len || len == 0) {
     599               0 :                 *p = start + 2;
     600               0 :                 return 0;
     601                 :         }
     602                 : 
     603               0 :         class_name = (char*)YYCURSOR;
     604                 : 
     605               0 :         YYCURSOR += len;
     606                 : 
     607               0 :         if (*(YYCURSOR) != '"') {
     608               0 :                 *p = YYCURSOR;
     609               0 :                 return 0;
     610                 :         }
     611               0 :         if (*(YYCURSOR+1) != ':') {
     612               0 :                 *p = YYCURSOR+1;
     613               0 :                 return 0;
     614                 :         }
     615                 : 
     616               0 :         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");
     617               0 :         if (len3 != len)
     618                 :         {
     619               0 :                 *p = YYCURSOR + len3 - len;
     620               0 :                 return 0;
     621                 :         }
     622                 : 
     623               0 :         class_name = estrndup(class_name, len);
     624                 : 
     625                 :         do {
     626                 :                 /* Try to find class directly */
     627               0 :                 if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
     628               0 :                         ce = *pce;
     629               0 :                         break;
     630                 :                 }
     631                 :                 
     632                 :                 /* Check for unserialize callback */
     633               0 :                 if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
     634               0 :                         incomplete_class = 1;
     635               0 :                         ce = PHP_IC_ENTRY;
     636               0 :                         break;
     637                 :                 }
     638                 :                 
     639                 :                 /* Call unserialize callback */
     640               0 :                 MAKE_STD_ZVAL(user_func);
     641               0 :                 ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
     642               0 :                 args[0] = &arg_func_name;
     643               0 :                 MAKE_STD_ZVAL(arg_func_name);
     644               0 :                 ZVAL_STRING(arg_func_name, class_name, 1);
     645               0 :                 if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
     646               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
     647               0 :                         incomplete_class = 1;
     648               0 :                         ce = PHP_IC_ENTRY;
     649               0 :                         zval_ptr_dtor(&user_func);
     650               0 :                         zval_ptr_dtor(&arg_func_name);
     651               0 :                         break;
     652                 :                 }
     653               0 :                 if (retval_ptr) {
     654               0 :                         zval_ptr_dtor(&retval_ptr);
     655                 :                 }
     656                 :                 
     657                 :                 /* The callback function may have defined the class */
     658               0 :                 if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
     659               0 :                         ce = *pce;
     660                 :                 } else {
     661               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val);
     662               0 :                         incomplete_class = 1;
     663               0 :                         ce = PHP_IC_ENTRY;
     664                 :                 }
     665                 : 
     666               0 :                 zval_ptr_dtor(&user_func);
     667               0 :                 zval_ptr_dtor(&arg_func_name);
     668               0 :                 break;
     669                 :         } while (1);
     670                 : 
     671               0 :         *p = YYCURSOR;
     672                 : 
     673               0 :         if(custom_object) {
     674               0 :                 efree(class_name);
     675               0 :                 return object_custom(UNSERIALIZE_PASSTHRU, ce);
     676                 :         }
     677                 :         
     678               0 :         elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
     679                 : 
     680               0 :         if (incomplete_class) {
     681               0 :                 php_store_class_name(*rval, class_name, len2);
     682                 :         }
     683               0 :         efree(class_name);
     684                 : 
     685               0 :         return object_common2(UNSERIALIZE_PASSTHRU, elements);
     686                 : }
     687                 : 
     688                 : "}" {
     689                 :         /* this is the case where we have less data than planned */
     690               0 :         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
     691               0 :         return 0; /* not sure if it should be 0 or 1 here? */
     692                 : }
     693                 : 
     694               0 : any     { return 0; }
     695                 : 
     696                 : */
     697                 : 
     698                 :         return 0;
     699                 : }

Generated by: LTP GCOV extension version 1.5