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_HEAD/lcov_data/ext/standard - var_unserializer.re
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 402
Code covered: 84.6 % Executed lines: 340
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:46 +0000 (34 hours ago)

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