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_2/lcov_data/ext/standard - var_unserializer.re
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 349
Code covered: 86.0 % Executed lines: 300
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 277375 2009-03-17 23:10:13Z 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             971 : {
      36             971 :         var_entries *var_hash = var_hashx->first, *prev = NULL;
      37                 : 
      38            1942 :         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             971 :         if (!var_hash) {
      44             335 :                 var_hash = emalloc(sizeof(var_entries));
      45             335 :                 var_hash->used_slots = 0;
      46             335 :                 var_hash->next = 0;
      47                 : 
      48             335 :                 if (!var_hashx->first)
      49             335 :                         var_hashx->first = var_hash;
      50                 :                 else
      51               0 :                         prev->next = var_hash;
      52                 :         }
      53                 : 
      54             971 :         var_hash->data[var_hash->used_slots++] = *rval;
      55             971 : }
      56                 : 
      57                 : static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
      58             152 : {
      59             152 :         var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
      60                 : 
      61             304 :         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             152 :         if (!var_hash) {
      67              37 :                 var_hash = emalloc(sizeof(var_entries));
      68              37 :                 var_hash->used_slots = 0;
      69              37 :                 var_hash->next = 0;
      70                 : 
      71              37 :                 if (!var_hashx->first_dtor)
      72              37 :                         var_hashx->first_dtor = var_hash;
      73                 :                 else
      74               0 :                         prev->next = var_hash;
      75                 :         }
      76                 : 
      77             152 :         (*rval)->refcount++;
      78             152 :         var_hash->data[var_hash->used_slots++] = *rval;
      79             152 : }
      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              95 : {
      99              95 :         var_entries *var_hash = var_hashx->first;
     100                 :         
     101             190 :         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              95 :         if (!var_hash) return !SUCCESS;
     107                 : 
     108              95 :         if (id < 0 || id >= var_hash->used_slots) return !SUCCESS;
     109                 : 
     110              95 :         *store = &var_hash->data[id];
     111                 : 
     112              95 :         return SUCCESS;
     113                 : }
     114                 : 
     115                 : PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
     116             636 : {
     117                 :         void *next;
     118                 :         long i;
     119             636 :         var_entries *var_hash = var_hashx->first;
     120                 :         
     121            1607 :         while (var_hash) {
     122             335 :                 next = var_hash->next;
     123             335 :                 efree(var_hash);
     124             335 :                 var_hash = next;
     125                 :         }
     126                 : 
     127             636 :         var_hash = var_hashx->first_dtor;
     128                 :         
     129            1309 :         while (var_hash) {
     130             189 :                 for (i = 0; i < var_hash->used_slots; i++) {
     131             152 :                         zval_ptr_dtor(&var_hash->data[i]);
     132                 :                 }
     133              37 :                 next = var_hash->next;
     134              37 :                 efree(var_hash);
     135              37 :                 var_hash = next;
     136                 :         }
     137             636 : }
     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            1053 : {
     204                 :         char cursor;
     205            1053 :         long result = 0;
     206            1053 :         int neg = 0;
     207                 : 
     208            1053 :         switch (*p) {
     209                 :                 case '-':
     210              10 :                         neg++;
     211                 :                         /* fall-through */
     212                 :                 case '+':
     213              10 :                         p++;
     214                 :         }
     215                 :         
     216                 :         while (1) {
     217            2262 :                 cursor = (char)*p;
     218            2262 :                 if (cursor >= '0' && cursor <= '9') {
     219            1209 :                         result = result * 10 + cursor - '0';
     220                 :                 } else {
     221                 :                         break;
     222                 :                 }
     223            1209 :                 p++;
     224            1209 :         }
     225            1053 :         if (q) *q = p;
     226            1053 :         if (neg) return -result;
     227            1043 :         return result;
     228                 : }
     229                 : 
     230                 : static inline long parse_iv(const unsigned char *p)
     231             927 : {
     232             927 :         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             664 : {
     238                 :         unsigned char cursor;
     239             664 :         size_t result = 0;
     240                 : 
     241             664 :         if (*p == '+') {
     242               0 :                 p++;
     243                 :         }
     244                 :         
     245                 :         while (1) {
     246            1418 :                 cursor = *p;
     247            1418 :                 if (cursor >= '0' && cursor <= '9') {
     248             754 :                         result = result * 10 + (size_t)(cursor - (unsigned char)'0');
     249                 :                 } else {
     250                 :                         break;
     251                 :                 }
     252             754 :                 p++;
     253             754 :         }
     254             664 :         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             286 : {
     262            1216 :         while (elements-- > 0) {
     263                 :                 zval *key, *data, **old_data;
     264                 : 
     265             672 :                 ALLOC_INIT_ZVAL(key);
     266                 : 
     267             672 :                 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             659 :                 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             659 :                 ALLOC_INIT_ZVAL(data);
     280                 : 
     281             659 :                 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             646 :                 switch (Z_TYPE_P(key)) {
     290                 :                         case IS_LONG:
     291             318 :                                 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             318 :                                 zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL);
     295             318 :                                 break;
     296                 :                         case IS_STRING:
     297             328 :                                 if (zend_symtable_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
     298             152 :                                         var_push_dtor(var_hash, old_data);
     299                 :                                 }
     300             328 :                                 zend_symtable_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
     301                 :                                 break;
     302                 :                 }
     303                 :                 
     304             646 :                 zval_dtor(key);
     305             646 :                 FREE_ZVAL(key);
     306                 : 
     307             646 :                 if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
     308               2 :                         (*p)--;
     309               2 :                         return 0;
     310                 :                 }
     311                 :         }
     312                 : 
     313             258 :         return 1;
     314                 : }
     315                 : 
     316                 : static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
     317             264 : {
     318             264 :         if (*((*p)++) == '}')
     319             262 :                 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               8 : {
     329                 :         long datalen;
     330                 : 
     331               8 :         if (ce->unserialize == NULL) {
     332               2 :                 zend_error(E_WARNING, "Class %s has no unserializer", ce->name);
     333               2 :                 return 0;
     334                 :         }
     335                 : 
     336               6 :         datalen = parse_iv2((*p) + 2, p);
     337                 : 
     338               6 :         (*p) += 2;
     339                 : 
     340               6 :         if (datalen < 0 || (*p) + datalen >= max) {
     341               0 :                 zend_error(E_WARNING, "Insufficient data for unserializing - %ld required, %ld present", datalen, (long)(max - (*p)));
     342               0 :                 return 0;
     343                 :         }
     344                 : 
     345               6 :         if (ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) {
     346               0 :                 return 0;
     347                 :         }
     348                 : 
     349               6 :         (*p) += datalen;
     350                 : 
     351               6 :         return finish_nested_data(UNSERIALIZE_PASSTHRU);
     352                 : }
     353                 : 
     354                 : static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
     355             120 : {
     356                 :         long elements;
     357                 :         
     358             120 :         elements = parse_iv2((*p) + 2, p);
     359                 : 
     360             120 :         (*p) += 2;
     361                 :         
     362             120 :         object_init_ex(*rval, ce);
     363             120 :         return elements;
     364                 : }
     365                 : 
     366                 : static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
     367             120 : {
     368             120 :         zval *retval_ptr = NULL;
     369                 :         zval fname;
     370                 : 
     371             120 :         if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements)) {
     372               0 :                 return 0;
     373                 :         }
     374                 : 
     375             120 :         if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
     376                 :                 zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) {
     377               6 :                 INIT_PZVAL(&fname);
     378               6 :                 ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0);
     379               6 :                 call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
     380                 :         }
     381                 : 
     382             120 :         if (retval_ptr)
     383               6 :                 zval_ptr_dtor(&retval_ptr);
     384                 : 
     385             120 :         return finish_nested_data(UNSERIALIZE_PASSTHRU);
     386                 : 
     387                 : }
     388                 : 
     389                 : PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
     390            1737 : {
     391                 :         const unsigned char *cursor, *limit, *marker, *start;
     392                 :         zval **rval_ref;
     393                 : 
     394            1737 :         limit = cursor = *p;
     395                 :         
     396            1737 :         if (var_hash && cursor[0] != 'R') {
     397             971 :                 var_push(var_hash, rval);
     398                 :         }
     399                 : 
     400            1737 :         start = cursor;
     401                 : 
     402                 :         
     403                 :         
     404                 : /*!re2c
     405                 : 
     406                 : "R:" iv ";"         {
     407                 :         long id;
     408                 : 
     409              85 :         *p = YYCURSOR;
     410              85 :         if (!var_hash) return 0;
     411                 : 
     412              85 :         id = parse_iv(start + 2) - 1;
     413              85 :         if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
     414               0 :                 return 0;
     415                 :         }
     416                 : 
     417              85 :         if (*rval != NULL) {
     418              85 :                 zval_ptr_dtor(rval);
     419                 :         }
     420              85 :         *rval = *rval_ref;
     421              85 :         (*rval)->refcount++;
     422              85 :         (*rval)->is_ref = 1;
     423                 :         
     424              85 :         return 1;
     425                 : }
     426                 : 
     427                 : "r:" iv ";"         {
     428                 :         long id;
     429                 : 
     430              10 :         *p = YYCURSOR;
     431              10 :         if (!var_hash) return 0;
     432                 : 
     433              10 :         id = parse_iv(start + 2) - 1;
     434              10 :         if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
     435               0 :                 return 0;
     436                 :         }
     437                 : 
     438              10 :         if (*rval == *rval_ref) return 0;
     439                 : 
     440              10 :         if (*rval != NULL) {
     441              10 :                 zval_ptr_dtor(rval);
     442                 :         }
     443              10 :         *rval = *rval_ref;
     444              10 :         (*rval)->refcount++;
     445              10 :         (*rval)->is_ref = 0;
     446                 :         
     447              10 :         return 1;
     448                 : }
     449                 : 
     450                 : "N;"  {
     451              53 :         *p = YYCURSOR;
     452              53 :         INIT_PZVAL(*rval);
     453              53 :         ZVAL_NULL(*rval);
     454              53 :         return 1;
     455                 : }
     456                 : 
     457                 : "b:" [01] ";"       {
     458              32 :         *p = YYCURSOR;
     459              32 :         INIT_PZVAL(*rval);
     460              32 :         ZVAL_BOOL(*rval, parse_iv(start + 2));
     461              32 :         return 1;
     462                 : }
     463                 : 
     464                 : "i:" iv ";" {
     465                 : #if SIZEOF_LONG == 4
     466             635 :         int digits = YYCURSOR - start - 3;
     467                 : 
     468             635 :         if (start[2] == '-' || start[2] == '+') {
     469              10 :                 digits--;
     470                 :         }
     471                 : 
     472                 :         /* Use double for large long values that were serialized on a 64-bit system */
     473             635 :         if (digits >= MAX_LENGTH_OF_LONG - 1) {
     474               8 :                 if (digits == MAX_LENGTH_OF_LONG - 1) {
     475               8 :                         int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
     476                 : 
     477               8 :                         if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
     478                 :                                 goto use_double;
     479                 :                         }
     480                 :                 } else {
     481               0 :                         goto use_double;
     482                 :                 }
     483                 :         }
     484                 : #endif
     485             634 :         *p = YYCURSOR;
     486             634 :         INIT_PZVAL(*rval);
     487             634 :         ZVAL_LONG(*rval, parse_iv(start + 2));
     488             634 :         return 1;
     489                 : }
     490                 : 
     491                 : "d:" ("NAN" | "-"? "INF") ";" {
     492               3 :         *p = YYCURSOR;
     493               3 :         INIT_PZVAL(*rval);
     494                 : 
     495               3 :         if (!strncmp(start + 2, "NAN", 3)) {
     496               1 :                 ZVAL_DOUBLE(*rval, php_get_nan());
     497               2 :         } else if (!strncmp(start + 2, "INF", 3)) {
     498               1 :                 ZVAL_DOUBLE(*rval, php_get_inf());
     499               1 :         } else if (!strncmp(start + 2, "-INF", 4)) {
     500               1 :                 ZVAL_DOUBLE(*rval, -php_get_inf());
     501                 :         }
     502                 : 
     503               3 :         return 1;
     504                 : }
     505                 : 
     506                 : "d:" (iv | nv | nvexp) ";"  {
     507                 : #if SIZEOF_LONG == 4
     508              49 : use_double:
     509                 : #endif
     510              49 :         *p = YYCURSOR;
     511              49 :         INIT_PZVAL(*rval);
     512              49 :         ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
     513              49 :         return 1;
     514                 : }
     515                 : 
     516                 : "s:" uiv ":" ["]       {
     517                 :         size_t len, maxlen;
     518                 :         char *str;
     519                 : 
     520             532 :         len = parse_uiv(start + 2);
     521             532 :         maxlen = max - YYCURSOR;
     522             532 :         if (maxlen < len) {
     523               3 :                 *p = start + 2;
     524               3 :                 return 0;
     525                 :         }
     526                 : 
     527             529 :         str = (char*)YYCURSOR;
     528                 : 
     529             529 :         YYCURSOR += len;
     530                 : 
     531             529 :         if (*(YYCURSOR) != '"') {
     532               2 :                 *p = YYCURSOR;
     533               2 :                 return 0;
     534                 :         }
     535                 : 
     536             527 :         YYCURSOR += 2;
     537             527 :         *p = YYCURSOR;
     538                 : 
     539             527 :         INIT_PZVAL(*rval);
     540             527 :         ZVAL_STRINGL(*rval, str, len, 1);
     541             527 :         return 1;
     542                 : }
     543                 : 
     544                 : "S:" uiv ":" ["]       {
     545                 :         size_t len, maxlen;
     546                 :         char *str;
     547                 : 
     548               1 :         len = parse_uiv(start + 2);
     549               1 :         maxlen = max - YYCURSOR;
     550               1 :         if (maxlen < len) {
     551               0 :                 *p = start + 2;
     552               0 :                 return 0;
     553                 :         }
     554                 : 
     555               1 :         if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) {
     556               1 :                 return 0;
     557                 :         }
     558                 : 
     559               0 :         if (*(YYCURSOR) != '"') {
     560               0 :                 efree(str);
     561               0 :                 *p = YYCURSOR;
     562               0 :                 return 0;
     563                 :         }
     564                 : 
     565               0 :         YYCURSOR += 2;
     566               0 :         *p = YYCURSOR;
     567                 : 
     568               0 :         INIT_PZVAL(*rval);
     569               0 :         ZVAL_STRINGL(*rval, str, len, 0);
     570               0 :         return 1;
     571                 : }
     572                 : 
     573                 : "a:" uiv ":" "{" {
     574             166 :         long elements = parse_iv(start + 2);
     575                 :         /* use iv() not uiv() in order to check data range */
     576             166 :         *p = YYCURSOR;
     577                 : 
     578             166 :         if (elements < 0) {
     579               0 :                 return 0;
     580                 :         }
     581                 : 
     582             166 :         INIT_PZVAL(*rval);
     583             166 :         Z_TYPE_PP(rval) = IS_ARRAY;
     584             166 :         ALLOC_HASHTABLE(Z_ARRVAL_PP(rval));
     585                 : 
     586             166 :         zend_hash_init(Z_ARRVAL_PP(rval), elements + 1, NULL, ZVAL_PTR_DTOR, 0);
     587                 : 
     588             166 :         if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements)) {
     589              28 :                 return 0;
     590                 :         }
     591                 : 
     592             138 :         return finish_nested_data(UNSERIALIZE_PASSTHRU);
     593                 : }
     594                 : 
     595                 : "o:" iv ":" ["] {
     596                 : 
     597               0 :         INIT_PZVAL(*rval);
     598                 :         
     599               0 :         return object_common2(UNSERIALIZE_PASSTHRU,
     600                 :                         object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
     601                 : }
     602                 : 
     603                 : object ":" uiv ":" ["] {
     604                 :         size_t len, len2, len3, maxlen;
     605                 :         long elements;
     606                 :         char *class_name;
     607                 :         zend_class_entry *ce;
     608                 :         zend_class_entry **pce;
     609             131 :         int incomplete_class = 0;
     610                 : 
     611             131 :         int custom_object = 0;
     612                 : 
     613                 :         zval *user_func;
     614                 :         zval *retval_ptr;
     615                 :         zval **args[1];
     616                 :         zval *arg_func_name;
     617                 : 
     618             131 :         if (*start == 'C') {
     619               8 :                 custom_object = 1;
     620                 :         }
     621                 :         
     622             131 :         INIT_PZVAL(*rval);
     623             131 :         len2 = len = parse_uiv(start + 2);
     624             131 :         maxlen = max - YYCURSOR;
     625             131 :         if (maxlen < len || len == 0) {
     626               1 :                 *p = start + 2;
     627               1 :                 return 0;
     628                 :         }
     629                 : 
     630             130 :         class_name = (char*)YYCURSOR;
     631                 : 
     632             130 :         YYCURSOR += len;
     633                 : 
     634             130 :         if (*(YYCURSOR) != '"') {
     635               1 :                 *p = YYCURSOR;
     636               1 :                 return 0;
     637                 :         }
     638             129 :         if (*(YYCURSOR+1) != ':') {
     639               1 :                 *p = YYCURSOR+1;
     640               1 :                 return 0;
     641                 :         }
     642                 : 
     643             128 :         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");
     644             128 :         if (len3 != len)
     645                 :         {
     646               0 :                 *p = YYCURSOR + len3 - len;
     647               0 :                 return 0;
     648                 :         }
     649                 : 
     650             128 :         class_name = estrndup(class_name, len);
     651                 : 
     652                 :         do {
     653                 :                 /* Try to find class directly */
     654             128 :                 if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
     655             112 :                         ce = *pce;
     656             112 :                         break;
     657                 :                 }
     658                 :                 
     659                 :                 /* Check for unserialize callback */
     660              16 :                 if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
     661               8 :                         incomplete_class = 1;
     662               8 :                         ce = PHP_IC_ENTRY;
     663               8 :                         break;
     664                 :                 }
     665                 :                 
     666                 :                 /* Call unserialize callback */
     667               8 :                 MAKE_STD_ZVAL(user_func);
     668               8 :                 ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
     669               8 :                 args[0] = &arg_func_name;
     670               8 :                 MAKE_STD_ZVAL(arg_func_name);
     671               8 :                 ZVAL_STRING(arg_func_name, class_name, 1);
     672               8 :                 if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
     673               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
     674               1 :                         incomplete_class = 1;
     675               1 :                         ce = PHP_IC_ENTRY;
     676               1 :                         zval_ptr_dtor(&user_func);
     677               1 :                         zval_ptr_dtor(&arg_func_name);
     678               1 :                         break;
     679                 :                 }
     680               7 :                 if (retval_ptr) {
     681               6 :                         zval_ptr_dtor(&retval_ptr);
     682                 :                 }
     683                 :                 
     684                 :                 /* The callback function may have defined the class */
     685               7 :                 if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
     686               4 :                         ce = *pce;
     687                 :                 } else {
     688               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);
     689               3 :                         incomplete_class = 1;
     690               3 :                         ce = PHP_IC_ENTRY;
     691                 :                 }
     692                 : 
     693               7 :                 zval_ptr_dtor(&user_func);
     694               7 :                 zval_ptr_dtor(&arg_func_name);
     695               7 :                 break;
     696                 :         } while (1);
     697                 : 
     698             128 :         *p = YYCURSOR;
     699                 : 
     700             128 :         if (custom_object) {
     701               8 :                 efree(class_name);
     702               8 :                 return object_custom(UNSERIALIZE_PASSTHRU, ce);
     703                 :         }
     704                 :         
     705             120 :         elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
     706                 : 
     707             120 :         if (incomplete_class) {
     708              11 :                 php_store_class_name(*rval, class_name, len2);
     709                 :         }
     710             120 :         efree(class_name);
     711                 : 
     712             120 :         return object_common2(UNSERIALIZE_PASSTHRU, elements);
     713                 : }
     714                 : 
     715                 : "}" {
     716                 :         /* this is the case where we have less data than planned */
     717               0 :         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
     718               0 :         return 0; /* not sure if it should be 0 or 1 here? */
     719                 : }
     720                 : 
     721              41 : any     { return 0; }
     722                 : 
     723                 : */
     724                 : 
     725                 :         return 0;
     726                 : }

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:28 +0000 (5 days ago)

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