PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_5_3/lcov_data/ext/standard - var_unserializer.re
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 350
Code covered: 86.0 % Executed lines: 301
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:15 +0000 (3 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.