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 - standard - var.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 616
Code covered: 89.4 % Executed lines: 551
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                 :    | Authors: Jani Lehtimäki <jkl@njet.net>                               |
      16                 :    |          Thies C. Arntzen <thies@thieso.net>                         |
      17                 :    |          Sascha Schumann <sascha@schumann.cx>                        |
      18                 :    +----------------------------------------------------------------------+
      19                 : */
      20                 : 
      21                 : /* $Id: var.c 287123 2009-08-11 22:46:07Z stas $ */
      22                 : 
      23                 : /* {{{ includes
      24                 : */
      25                 : #include <stdio.h>
      26                 : #include <stdlib.h>
      27                 : #include <errno.h>
      28                 : #include "php.h"
      29                 : #include "php_string.h"
      30                 : #include "php_var.h"
      31                 : #include "php_smart_str.h"
      32                 : #include "basic_functions.h"
      33                 : #include "php_incomplete_class.h"
      34                 : 
      35                 : #define COMMON (Z_ISREF_PP(struc) ? "&" : "")
      36                 : /* }}} */
      37                 : 
      38                 : static void php_var_dump_unicode(UChar *ustr, int length, int verbose, char *quote, int escape TSRMLS_DC) /* {{{ */
      39           60705 : {
      40                 :         UChar32 c;
      41                 :         int i;
      42           60705 :         UErrorCode status = U_ZERO_ERROR;
      43                 :         int clen;
      44           60705 :         char *out = NULL;
      45                 : 
      46           60705 :         if (length == 0) {
      47            3135 :                 ZEND_PUTS(quote);
      48            3135 :                 ZEND_PUTS(quote);
      49            3135 :                 return;
      50                 :         }
      51                 : 
      52           57570 :         zend_unicode_to_string_ex(ZEND_U_CONVERTER(UG(output_encoding_conv)), &out, &clen, ustr, length, &status);
      53           57570 :         if (U_FAILURE(status)) {
      54               0 :                 php_printf("problem converting string from Unicode: %s\n", u_errorName(status));
      55               0 :                 efree(out);
      56               0 :                 return;
      57                 :         }
      58                 : 
      59           57570 :         ZEND_PUTS(quote);
      60           57570 :         if (escape) {
      61                 :                 char *str;
      62                 :                 int str_len;
      63                 : 
      64              91 :                 str = php_addcslashes(out, clen, &str_len, 0, "'\\", 2 TSRMLS_CC);
      65              91 :                 PHPWRITE(str, str_len);
      66              91 :                 efree(str);
      67                 :         } else {
      68           57479 :                 PHPWRITE(out, clen);
      69                 :         }
      70           57570 :         ZEND_PUTS(quote);
      71           57570 :         if (verbose) {
      72             158 :                 ZEND_PUTS(" {");
      73                 :                 /* output the code points (not code units) */
      74             158 :                 if (length>=0) {
      75                 :                         /* s is not NUL-terminated */
      76             990 :                         for (i = 0; i < length; /* U16_NEXT post-increments */) {
      77             674 :                                 U16_NEXT(ustr, i, length, c);
      78             674 :                                 php_printf(" %04x", c);
      79                 :                         }
      80                 :                 } else {
      81                 :                         /* s is NUL-terminated */
      82               0 :                         for (i = 0; /* condition in loop body */; /* U16_NEXT post-increments */) {
      83               0 :                                 U16_NEXT(ustr, i, length, c);
      84               0 :                                 if (c == 0) {
      85               0 :                                         break;
      86                 :                                 }
      87               0 :                                 php_printf(" %04x", c);
      88               0 :                         }
      89                 :                 }
      90             158 :                 php_printf(" }");
      91                 :         }
      92           57570 :         efree(out);
      93                 : }
      94                 : /* }}} */
      95                 : 
      96                 : static int php_array_element_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
      97           61394 : {
      98                 :         int level;
      99                 :         int verbose;
     100                 : 
     101           61394 :         level = va_arg(args, int);
     102           61394 :         verbose = va_arg(args, int);
     103                 : 
     104           61394 :         if (hash_key->nKeyLength == 0) { /* numeric key */
     105           44528 :                 php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
     106                 :         } else { /* string key */
     107           16866 :                 php_printf("%*c[", level + 1, ' ');
     108           16866 :                 if (hash_key->type == IS_STRING) {
     109            6324 :                         php_printf("\"");
     110            6324 :                         PHPWRITE(hash_key->arKey.s, hash_key->nKeyLength - 1);
     111            6324 :                         php_printf("\"");
     112           10542 :                 } else if (hash_key->type == IS_UNICODE) {
     113           10542 :                         php_printf("u");
     114           10542 :                         php_var_dump_unicode(hash_key->arKey.u, hash_key->nKeyLength-1, verbose, "\"", 0 TSRMLS_CC);
     115                 :                 }
     116           16866 :                 php_printf("]=>\n");
     117                 :         }
     118           61394 :         php_var_dump(zv, level + 2, verbose TSRMLS_CC);
     119           61394 :         return 0;
     120                 : }
     121                 : /* }}} */
     122                 : 
     123                 : static int php_object_property_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
     124            6330 : {
     125                 :         int level;
     126                 :         zstr prop_name, class_name;
     127                 :         int verbose;
     128                 : 
     129            6330 :         level = va_arg(args, int);
     130            6330 :         verbose = va_arg(args, int);
     131                 : 
     132            6330 :         if (hash_key->nKeyLength == 0) { /* numeric key */
     133              99 :                 php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
     134                 :         } else { /* string key */
     135            6231 :                 int is_unicode = hash_key->type == IS_UNICODE;
     136                 : 
     137            6231 :                 int unmangle = zend_u_unmangle_property_name(hash_key->type, hash_key->arKey, hash_key->nKeyLength-1, &class_name, &prop_name);
     138            6231 :                 php_printf("%*c[", level + 1, ' ');
     139                 : 
     140            7218 :                 if (class_name.s && unmangle == SUCCESS) {
     141             987 :                         if (class_name.s[0] == '*') {
     142             324 :                                 php_printf("%s\"%R\":protected", is_unicode ? "u" : "", hash_key->type, prop_name);
     143                 :                         } else {
     144             663 :                                 php_printf("%s\"%R\":%s\"%R\":private", is_unicode ? "u" : "", hash_key->type, prop_name, is_unicode ? "u" : "", hash_key->type, class_name);
     145                 :                         }
     146                 :                 } else {
     147            5244 :                         if (is_unicode) {
     148            5209 :                                 php_printf("u");
     149            5209 :                                 php_var_dump_unicode(hash_key->arKey.u, hash_key->nKeyLength-1, verbose, "\"", 0 TSRMLS_CC);
     150                 :                         } else {
     151              35 :                                 php_printf("\"");
     152              35 :                                 PHPWRITE(hash_key->arKey.s, hash_key->nKeyLength - 1);
     153              35 :                                 php_printf("\"");
     154                 :                         }
     155                 :                 }
     156            6231 :                 ZEND_PUTS("]=>\n");
     157                 :         }
     158            6330 :         php_var_dump(zv, level + 2, verbose TSRMLS_CC);
     159            6330 :         return 0;
     160                 : }
     161                 : /* }}} */
     162                 : 
     163                 : PHPAPI void php_var_dump(zval **struc, int level, int verbose TSRMLS_DC) /* {{{ */
     164          211813 : {
     165                 :         HashTable *myht;
     166                 :         zstr class_name;
     167                 :         zend_uint class_name_len;
     168                 :         int (*php_element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*);
     169                 :         int is_temp;
     170                 : 
     171          211813 :         if (level > 1) {
     172           67724 :                 php_printf("%*c", level - 1, ' ');
     173                 :         }
     174                 : 
     175          211813 :         switch (Z_TYPE_PP(struc)) {
     176                 :         case IS_BOOL:
     177           43106 :                 php_printf("%sbool(%s)\n", COMMON, Z_LVAL_PP(struc) ? "true" : "false");
     178           43105 :                 break;
     179                 :         case IS_NULL:
     180           18032 :                 php_printf("%sNULL\n", COMMON);
     181           18032 :                 break;
     182                 :         case IS_LONG:
     183           59656 :                 php_printf("%sint(%ld)\n", COMMON, Z_LVAL_PP(struc));
     184           59656 :                 break;
     185                 :         case IS_DOUBLE:
     186            5352 :                 php_printf("%sfloat(%.*G)\n", COMMON, (int) EG(precision), Z_DVAL_PP(struc));
     187            5352 :                 break;
     188                 :         case IS_STRING:
     189           14264 :                 php_printf("%sstring(%d) \"", COMMON, Z_STRLEN_PP(struc));
     190           14264 :                 PHPWRITE(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc));
     191           14264 :                 PUTS("\"\n");
     192           14264 :                 break;
     193                 :         case IS_UNICODE:
     194           44696 :                 php_printf("%sunicode(%d) ", COMMON, u_countChar32((*struc)->value.ustr.val, (*struc)->value.ustr.len));
     195           44696 :                 php_var_dump_unicode((*struc)->value.ustr.val, (*struc)->value.ustr.len, verbose, "\"", 0 TSRMLS_CC);
     196           44696 :                 PUTS("\n");
     197           44696 :                 break;
     198                 :         case IS_ARRAY:
     199           22349 :                 myht = Z_ARRVAL_PP(struc);
     200           22349 :                 if (myht->nApplyCount > 1) {
     201             110 :                         PUTS("*RECURSION*\n");
     202             110 :                         return;
     203                 :                 }
     204           22239 :                 php_printf("%sarray(%d) {\n", COMMON, zend_hash_num_elements(myht));
     205           22239 :                 php_element_dump_func = php_array_element_dump;
     206           22239 :                 is_temp = 0;
     207           22239 :                 goto head_done;
     208                 :         case IS_OBJECT:
     209            3553 :                 myht = Z_OBJDEBUG_PP(struc, is_temp);
     210            3553 :                 if (myht && myht->nApplyCount > 1) {
     211              91 :                         PUTS("*RECURSION*\n");
     212              91 :                         return;
     213                 :                 }
     214                 : 
     215            3462 :                 Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);
     216            3462 :                 php_printf("%sobject(%v)#%d (%d) {\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0);
     217            3462 :                 efree(class_name.v);
     218            3462 :                 php_element_dump_func = php_object_property_dump;
     219           25701 : head_done:
     220           25701 :                 if (myht) {
     221           25693 :                         zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) php_element_dump_func, 2, level, verbose);
     222           25693 :                         if (is_temp) {
     223             204 :                                 zend_hash_destroy(myht);
     224             204 :                                 efree(myht);
     225                 :                         }
     226                 :                 }
     227           25701 :                 if (level > 1) {
     228            5935 :                         php_printf("%*c", level-1, ' ');
     229                 :                 }
     230           25701 :                 PUTS("}\n");
     231           25701 :                 break;
     232                 :         case IS_RESOURCE: {
     233                 :                 char *type_name;
     234                 : 
     235             805 :                 type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(struc) TSRMLS_CC);
     236             805 :                 php_printf("%sresource(%ld) of type (%s)\n", COMMON, Z_LVAL_PP(struc), type_name ? type_name : "Unknown");
     237             805 :                 break;
     238                 :         }
     239                 :         default:
     240               0 :                 php_printf("%sUNKNOWN:0\n", COMMON);
     241                 :                 break;
     242                 :         }
     243                 : }
     244                 : /* }}} */
     245                 : 
     246                 : /* {{{ proto void var_dump(mixed var) U
     247                 :    Dumps a string representation of variable to output */
     248                 : PHP_FUNCTION(var_dump)
     249          142722 : {
     250          142722 :         zval ***args = NULL;
     251                 :         int argc;
     252                 :         int     i;
     253                 : 
     254          142722 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
     255               1 :                 return;
     256                 :         }
     257                 : 
     258          286809 :         for (i = 0; i < argc; i++) {
     259          144089 :                 php_var_dump(args[i], 1, 0 TSRMLS_CC);
     260                 :         }
     261          142720 :         efree(args);
     262                 : }
     263                 : /* }}} */
     264                 : 
     265                 : /* {{{ proto void var_inspect(mixed var) U
     266                 :    Dumps a string representation of variable to output (verbose form) */
     267                 : PHP_FUNCTION(var_inspect)
     268               0 : {
     269               0 :         zval ***args = NULL;
     270                 :         int argc;
     271                 :         int     i;
     272                 :         
     273               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
     274               0 :                 return;
     275                 :         }
     276                 : 
     277               0 :         for (i = 0; i < argc; i++) {
     278               0 :                 php_var_dump(args[i], 1, 1 TSRMLS_CC);
     279                 :         }
     280               0 :         efree(args);
     281                 : }
     282                 : /* }}} */
     283                 : 
     284                 : static int zval_array_element_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
     285             143 : {
     286                 :         int level;
     287                 : 
     288             143 :         level = va_arg(args, int);
     289                 : 
     290             143 :         if (hash_key->nKeyLength == 0) { /* numeric key */
     291              54 :                 php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
     292                 :         } else { /* string key */
     293                 :                 /* XXX: perphaps when we are inside the class we should permit access to
     294                 :                  * private & protected values
     295                 :                  */
     296              89 :                 if (va_arg(args, int) &&
     297                 :                         ((hash_key->type == IS_STRING && hash_key->arKey.s[0] == 0) ||
     298                 :                         (hash_key->type == IS_UNICODE && hash_key->arKey.u[0] == 0))
     299                 :                 ) {
     300               0 :                         return 0;
     301                 :                 }
     302              89 :                 php_printf("%*c[", level + 1, ' ');
     303              89 :                 if (hash_key->type == IS_STRING) {
     304               0 :                         php_printf("\"");
     305               0 :                         PHPWRITE(hash_key->arKey.s, hash_key->nKeyLength - 1);
     306               0 :                         php_printf("\"");
     307              89 :                 } else if (hash_key->type == IS_UNICODE) {
     308              89 :                         php_printf("u");
     309              89 :                         php_var_dump_unicode(hash_key->arKey.u, hash_key->nKeyLength-1, 1, "\"", 0 TSRMLS_CC);
     310                 :                 }
     311              89 :                 php_printf("]=>\n");
     312                 :         }
     313             143 :         php_debug_zval_dump(zv, level + 2, 1 TSRMLS_CC);
     314             143 :         return 0;
     315                 : }
     316                 : /* }}} */
     317                 : 
     318                 : static int zval_object_property_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
     319             242 : {
     320                 :         int level;
     321                 :         zstr prop_name, class_name;
     322                 :         int verbose;
     323                 : 
     324             242 :         level = va_arg(args, int);
     325             242 :         verbose = va_arg(args, int);
     326                 : 
     327             242 :         if (hash_key->nKeyLength == 0) { /* numeric key */
     328               0 :                 php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
     329                 :         } else { /* string key */
     330             242 :                 int is_unicode = hash_key->type == IS_UNICODE;
     331                 : 
     332             242 :                 zend_u_unmangle_property_name(hash_key->type, hash_key->arKey, hash_key->nKeyLength - 1, &class_name, &prop_name);
     333             242 :                 php_printf("%*c[", level + 1, ' ');
     334                 : 
     335             242 :                 if (class_name.s) {
     336              78 :                         if (class_name.s[0]=='*') {
     337              39 :                                 php_printf("%s\"%R\":protected", is_unicode ? "u" : "", hash_key->type, prop_name);
     338                 :                         } else {
     339              39 :                                 php_printf("%s\"%R\":%s\"%R\":private", is_unicode ? "u" : "", hash_key->type, prop_name, is_unicode ? "u" : "", hash_key->type, class_name);
     340                 :                         }
     341                 :                 } else {
     342             164 :                         php_printf("%s\"%R\"", is_unicode ? "u" : "", hash_key->type, prop_name);
     343                 :                 }
     344             242 :                 ZEND_PUTS("]=>\n");
     345                 :         }
     346             242 :         php_debug_zval_dump(zv, level + 2, 1 TSRMLS_CC);
     347             242 :         return 0;
     348                 : }
     349                 : /* }}} */
     350                 : 
     351                 : PHPAPI void php_debug_zval_dump(zval **struc, int level, int verbose TSRMLS_DC) /* {{{ */
     352             683 : {
     353             683 :         HashTable *myht = NULL;
     354                 :         zstr class_name;
     355                 :         zend_uint class_name_len;
     356                 :         zend_class_entry *ce;
     357                 :         int (*zval_element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*);
     358             683 :         int is_temp = 0;
     359                 : 
     360             683 :         if (level > 1) {
     361             385 :                 php_printf("%*c", level - 1, ' ');
     362                 :         }
     363                 : 
     364             683 :         switch (Z_TYPE_PP(struc)) {
     365                 :         case IS_BOOL:
     366              12 :                 php_printf("%sbool(%s) refcount(%u)\n", COMMON, Z_LVAL_PP(struc)?"true":"false", Z_REFCOUNT_PP(struc));
     367              12 :                 break;
     368                 :         case IS_NULL:
     369              25 :                 php_printf("%sNULL refcount(%u)\n", COMMON, Z_REFCOUNT_PP(struc));
     370              25 :                 break;
     371                 :         case IS_LONG:
     372             386 :                 php_printf("%slong(%ld) refcount(%u)\n", COMMON, Z_LVAL_PP(struc), Z_REFCOUNT_PP(struc));
     373             386 :                 break;
     374                 :         case IS_DOUBLE:
     375              38 :                 php_printf("%sdouble(%.*G) refcount(%u)\n", COMMON, (int) EG(precision), Z_DVAL_PP(struc), Z_REFCOUNT_PP(struc));
     376              38 :                 break;
     377                 :         case IS_STRING:
     378               0 :                 php_printf("%sstring(%d) \"", COMMON, Z_STRLEN_PP(struc));
     379               0 :                 PHPWRITE(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc));
     380               0 :                 php_printf("\" refcount(%u)\n", Z_REFCOUNT_PP(struc));
     381               0 :                 break;
     382                 :         case IS_UNICODE:
     383              77 :                 php_printf("%sunicode(%d) ", COMMON, u_countChar32((*struc)->value.ustr.val, (*struc)->value.ustr.len));
     384              77 :                 php_var_dump_unicode((*struc)->value.ustr.val, (*struc)->value.ustr.len, verbose, "\"", 0 TSRMLS_CC);
     385              77 :                 php_printf(" refcount(%u)\n", Z_REFCOUNT_PP(struc));
     386              77 :                 break;
     387                 :         case IS_ARRAY:
     388              77 :                 myht = Z_ARRVAL_PP(struc);
     389              77 :                 if (myht->nApplyCount > 1) {
     390               0 :                         PUTS("*RECURSION*\n");
     391               0 :                         return;
     392                 :                 }
     393              77 :                 php_printf("%sarray(%d) refcount(%u){\n", COMMON, zend_hash_num_elements(myht), Z_REFCOUNT_PP(struc));
     394              77 :                 zval_element_dump_func = zval_array_element_dump;
     395              77 :                 goto head_done;
     396                 :         case IS_OBJECT:
     397              66 :                 myht = Z_OBJDEBUG_PP(struc, is_temp);
     398              66 :                 if (myht && myht->nApplyCount > 1) {
     399              24 :                         PUTS("*RECURSION*\n");
     400              24 :                         return;
     401                 :                 }
     402              42 :                 ce = Z_OBJCE_PP(struc);
     403              42 :                 Z_OBJ_HANDLER_PP(struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);
     404              42 :                 php_printf("%sobject(%v)#%d (%d) refcount(%u){\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0, Z_REFCOUNT_PP(struc));
     405              42 :                 efree(class_name.v);
     406              42 :                 zval_element_dump_func = zval_object_property_dump;
     407             119 : head_done:
     408             119 :                 if (myht) {
     409             119 :                         zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) zval_element_dump_func, 1, level, (Z_TYPE_PP(struc) == IS_ARRAY ? 0 : 1));
     410             119 :                         if (is_temp) {
     411               1 :                                 zend_hash_destroy(myht);
     412               1 :                                 efree(myht);
     413                 :                         }
     414                 :                 }
     415             119 :                 if (level > 1) {
     416              79 :                         php_printf("%*c", level - 1, ' ');
     417                 :                 }
     418             119 :                 PUTS("}\n");
     419             119 :                 break;
     420                 :         case IS_RESOURCE: {
     421                 :                 char *type_name;
     422                 : 
     423               2 :                 type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(struc) TSRMLS_CC);
     424               2 :                 php_printf("%sresource(%ld) of type (%s) refcount(%u)\n", COMMON, Z_LVAL_PP(struc), type_name ? type_name : "Unknown", Z_REFCOUNT_PP(struc));
     425               2 :                 break;
     426                 :         }
     427                 :         default:
     428               0 :                 php_printf("%sUNKNOWN:0\n", COMMON);
     429                 :                 break;
     430                 :         }
     431                 : }
     432                 : /* }}} */
     433                 : 
     434                 : /* {{{ proto void debug_zval_dump(mixed var) U
     435                 :    Dumps a string representation of an internal zend value to output. */
     436                 : PHP_FUNCTION(debug_zval_dump)
     437             205 : {
     438             205 :         zval ***args = NULL;
     439                 :         int argc;
     440                 :         int     i;
     441                 : 
     442             205 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
     443               1 :                 return;
     444                 :         }
     445                 : 
     446             502 :         for (i = 0; i < argc; i++) {
     447             298 :                 php_debug_zval_dump(args[i], 1, 1 TSRMLS_CC);
     448                 :         }
     449             204 :         efree(args);
     450                 : }
     451                 : /* }}} */
     452                 : 
     453                 : static int php_array_element_export(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
     454            1313 : {
     455                 :         int level;
     456                 : 
     457            1313 :         level = va_arg(args, int);
     458                 : 
     459            1313 :         if (hash_key->nKeyLength == 0) { /* numeric key */
     460             596 :                 php_printf("%*c%ld => ", level + 1, ' ', hash_key->h);
     461                 :         } else { /* string key */
     462             717 :                 php_printf("%*c'", level + 1, ' ');
     463             717 :                 if (hash_key->type == IS_UNICODE) {
     464              92 :                         php_var_dump_unicode(hash_key->arKey.u, hash_key->nKeyLength-1, 0, "", 1 TSRMLS_CC);
     465                 :                 } else {
     466                 :                         char *key, *tmp_str;
     467                 :                         int key_len, tmp_len;
     468             625 :                         key = php_addcslashes(hash_key->arKey.s, hash_key->nKeyLength - 1, &key_len, 0, "'\\", 2 TSRMLS_CC);
     469             625 :                         tmp_str = php_str_to_str_ex(key, key_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len, 0, NULL);
     470             625 :                         PHPWRITE(tmp_str, tmp_len);
     471             625 :                         efree(key);
     472             625 :                         efree(tmp_str);
     473                 :                 }
     474             717 :                 php_printf("' => ");
     475                 :         }
     476            1313 :         php_var_export(zv, level + 2 TSRMLS_CC);
     477            1309 :         PUTS (",\n");
     478            1309 :         return 0;
     479                 : }
     480                 : /* }}} */
     481                 : 
     482                 : static int php_object_element_export(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
     483             283 : {
     484                 :         int level;
     485                 :         zstr prop_name, class_name;
     486                 : 
     487             283 :         level = va_arg(args, int);
     488                 : 
     489             283 :         php_printf("%*c", level + 1, ' ');
     490             283 :         if (hash_key->nKeyLength != 0) {
     491             280 :                 zend_u_unmangle_property_name(hash_key->type, hash_key->arKey, hash_key->nKeyLength - 1, &class_name, &prop_name);
     492             280 :                 php_printf(" '%R' => ", hash_key->type, prop_name);
     493                 :         } else {
     494               3 :                 php_printf(" %ld => ", hash_key->h);
     495                 :         }
     496             283 :         php_var_export(zv, level + 2 TSRMLS_CC);
     497             280 :         PUTS (",\n");
     498             280 :         return 0;
     499                 : }
     500                 : /* }}} */
     501                 : 
     502                 : static void php_unicode_export(UChar *ustr, int ustr_len TSRMLS_DC) /* {{{ */
     503             479 : {
     504                 :         UChar32 cp;
     505             479 :         int i = 0;
     506                 :         char buf[10];
     507                 :         int buf_len;
     508             479 :         int state = 0; /* 0 = in single quotes, 1 = in double quotes */
     509                 : 
     510                 :         /*
     511                 :          * We export all codepoints > 128 in escaped form to avoid encoding issues
     512                 :          * in case the result is used in a script.
     513                 :          */
     514            6600 :         while (i < ustr_len) {
     515            5642 :                 U16_NEXT(ustr, i, ustr_len, cp);
     516            5642 :                 switch (cp) {
     517                 :                         case 0x0: /* '\0' */
     518              19 :                                 if (state == 0) {
     519              19 :                                         PHPWRITE("' . \"", 5);
     520              19 :                                         state = 1;
     521                 :                                 }
     522              19 :                                 PHPWRITE("\\0", 2);
     523              19 :                                 break;
     524                 : 
     525                 :                         case 0x27: /* '\'' */
     526               1 :                                 if (state == 1) {
     527               0 :                                         PHPWRITE("\" . '", 5);
     528               0 :                                         state = 0;
     529                 :                                 }
     530               1 :                                 PHPWRITE("\\'", 2);
     531               1 :                                 break;
     532                 : 
     533                 :                         case 0x5c: /* '\\' */
     534              20 :                                 PHPWRITE("\\\\", 2);
     535              20 :                                 break;
     536                 : 
     537                 :                         default:
     538            5602 :                                 if ((uint32_t)cp < 128) {
     539            5602 :                                         if (state == 1) {
     540               9 :                                                 PHPWRITE("\" . '", 5);
     541               9 :                                                 state = 0;
     542                 :                                         }
     543            5602 :                                         buf[0] = (char) (short) cp;
     544            5602 :                                         buf_len = 1;
     545               0 :                                 } else if (U_IS_BMP(cp)) {
     546               0 :                                         if (state == 0) {
     547               0 :                                                 PHPWRITE("' . \"", 5);
     548               0 :                                                 state = 1;
     549                 :                                         }
     550               0 :                                         buf_len = snprintf(buf, sizeof(buf), "\\u%04X", cp);
     551                 :                                 } else {
     552               0 :                                         if (state == 0) {
     553               0 :                                                 PHPWRITE("' . \"", 5);
     554               0 :                                                 state = 1;
     555                 :                                         }
     556               0 :                                         buf_len = snprintf(buf, sizeof(buf), "\\u%06X", cp);
     557                 :                                 }
     558            5602 :                                 PHPWRITE(buf, buf_len);
     559                 :                                 break;
     560                 :                 }
     561                 :         }
     562             479 :         if (state == 1) { /* if we are in double quotes, go back to single */
     563              10 :                 PHPWRITE("\" . '", 5);
     564                 :         }
     565             479 : }
     566                 : /* }}} */
     567                 : 
     568                 : PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC) /* {{{ */
     569            2902 : {
     570                 :         HashTable *myht;
     571                 :         char *tmp_str, *tmp_str2;
     572                 :         int tmp_len, tmp_len2;
     573                 :         zstr class_name;
     574                 :         zend_uint class_name_len;
     575                 : 
     576            2902 :         switch (Z_TYPE_PP(struc)) {
     577                 :         case IS_BOOL:
     578              48 :                 php_printf("%s", Z_LVAL_PP(struc) ? "true" : "false");
     579              48 :                 break;
     580                 :         case IS_NULL:
     581             203 :                 php_printf("NULL");
     582             203 :                 break;
     583                 :         case IS_LONG:
     584             821 :                 php_printf("%ld", Z_LVAL_PP(struc));
     585             821 :                 break;
     586                 :         case IS_DOUBLE:
     587             117 :                 php_printf("%.*H", (int) EG(precision), Z_DVAL_PP(struc));
     588             117 :                 break;
     589                 :         case IS_STRING:
     590             493 :                 tmp_str = php_addcslashes(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc), &tmp_len, 0, "'\\", 2 TSRMLS_CC);
     591             493 :                 tmp_str2 = php_str_to_str_ex(tmp_str, tmp_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len2, 0, NULL);
     592             493 :                 PUTS ("'");
     593             493 :                 PHPWRITE(tmp_str2, tmp_len2);
     594             493 :                 PUTS ("'");
     595             493 :                 efree(tmp_str2);
     596             493 :                 efree(tmp_str);
     597             493 :                 break;
     598                 :         case IS_UNICODE:
     599             479 :                 PUTS ("'");
     600             479 :                 php_unicode_export(Z_USTRVAL_PP(struc), Z_USTRLEN_PP(struc) TSRMLS_CC);
     601             479 :                 PUTS ("'");
     602             479 :                 break;
     603                 :         case IS_ARRAY:
     604             527 :                 myht = Z_ARRVAL_PP(struc);
     605             527 :                 if (level > 1) {
     606             110 :                         php_printf("\n%*c", level - 1, ' ');
     607                 :                 }
     608             527 :                 PUTS ("array (\n");
     609             527 :                 zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) php_array_element_export, 1, level, 0);
     610             522 :                 if (level > 1) {
     611             106 :                         php_printf("%*c", level - 1, ' ');
     612                 :                 }
     613             522 :                 PUTS(")");
     614             522 :                 break;
     615                 :         case IS_OBJECT:
     616             214 :                 myht = Z_OBJPROP_PP(struc);
     617             214 :                 if (level > 1) {
     618             143 :                         php_printf("\n%*c", level - 1, ' ');
     619                 :                 }
     620             214 :                 Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);
     621             214 :                 php_printf ("%v::__set_state(array(\n", class_name);
     622             214 :                 efree(class_name.v);
     623             214 :                 if (myht) {
     624             214 :                         zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) php_object_element_export, 1, level);
     625                 :                 }
     626             210 :                 if (level > 1) {
     627             140 :                         php_printf("%*c", level - 1, ' ');
     628                 :                 }
     629             210 :                 php_printf ("))");
     630             210 :                 break;
     631                 :         default:
     632               0 :                 PUTS ("NULL");
     633                 :                 break;
     634                 :         }
     635            2893 : }
     636                 : /* }}} */
     637                 : 
     638                 : /* {{{ proto mixed var_export(mixed var [, bool return]) U
     639                 :    Outputs or returns a string representation of a variable */
     640                 : PHP_FUNCTION(var_export)
     641            1310 : {
     642                 :         zval *var;
     643            1310 :         zend_bool return_output = 0;
     644                 : 
     645            1310 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &return_output) == FAILURE) {
     646               4 :                 return;
     647                 :         }
     648                 : 
     649            1306 :         if (return_output) {
     650             961 :                 php_output_start_default(TSRMLS_C);
     651                 :         }
     652                 : 
     653                 :         /* UTODO
     654                 :          * We need to escape non-ASCII chars with \uXXXX format. php_var_export()
     655                 :          * currently uses output_encoding to export Unicode strings. Suppose it's
     656                 :          * set to utf-8. If you use the result of var_export() in non-utf-8 context,
     657                 :          * there may be trouble.
     658                 :          */
     659            1306 :         php_var_export(&var, 1 TSRMLS_CC);
     660                 : 
     661            1304 :         if (return_output) {
     662             959 :                 php_output_get_contents(return_value TSRMLS_CC);
     663             959 :                 php_output_discard(TSRMLS_C);
     664                 :         }
     665                 : }
     666                 : /* }}} */
     667                 : 
     668                 : static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC);
     669                 : 
     670                 : static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old TSRMLS_DC) /* {{{ */
     671           29011 : {
     672                 :         ulong var_no;
     673                 :         char id[32], *p;
     674                 :         register int len;
     675                 : 
     676                 :         /* relies on "(long)" being a perfect hash function for data pointers,
     677                 :          * however the actual identity of an object has had to be determined
     678                 :          * by its object handle and the class entry since 5.0. */
     679           29214 :         if ((Z_TYPE_P(var) == IS_OBJECT) && Z_OBJ_HT_P(var)->get_class_entry) {
     680             203 :                 p = smart_str_print_long(id + sizeof(id) - 1,
     681                 :                                 (((size_t)Z_OBJCE_P(var) << 5)
     682                 :                                 | ((size_t)Z_OBJCE_P(var) >> (sizeof(long) * 8 - 5)))
     683                 :                                 + (long) Z_OBJ_HANDLE_P(var));
     684             203 :                 *(--p) = 'O';
     685             203 :                 len = id + sizeof(id) - 1 - p;
     686                 :         } else {
     687           28808 :                 p = smart_str_print_long(id + sizeof(id) - 1, (long) var);
     688           28808 :                 len = id + sizeof(id) - 1 - p;
     689                 :         }
     690                 : 
     691           29011 :         if (var_old && zend_hash_find(var_hash, p, len, var_old) == SUCCESS) {
     692           27685 :                 if (!Z_ISREF_P(var)) {
     693                 :                         /* we still need to bump up the counter, since non-refs will
     694                 :                          * be counted separately by unserializer */
     695           27619 :                         var_no = -1;
     696           27619 :                         zend_hash_next_index_insert(var_hash, &var_no, sizeof(var_no), NULL);
     697                 :                 }
     698           27685 :                 return FAILURE;
     699                 :         }
     700                 : 
     701                 :         /* +1 because otherwise hash will think we are trying to store NULL pointer */
     702            1326 :         var_no = zend_hash_num_elements(var_hash) + 1;
     703            1326 :         zend_hash_add(var_hash, p, len, &var_no, sizeof(var_no), NULL);
     704            1326 :         return SUCCESS;
     705                 : }
     706                 : /* }}} */
     707                 : 
     708                 : static inline void php_var_serialize_long(smart_str *buf, long val) /* {{{ */
     709            6631 : {
     710            6631 :         smart_str_appendl(buf, "i:", 2);
     711            6631 :         smart_str_append_long(buf, val);
     712            6631 :         smart_str_appendc(buf, ';');
     713            6631 : }
     714                 : /* }}} */
     715                 : 
     716                 : static inline void php_var_serialize_string(smart_str *buf, char *str, int len) /* {{{ */
     717              46 : {
     718                 :         static const char hex[] = "0123456789abcdef";
     719                 :         unsigned char c;
     720                 :         int i;
     721                 : 
     722              46 :         smart_str_appendl(buf, "S:", 2);
     723              46 :         smart_str_append_long(buf, len);
     724              46 :         smart_str_appendl(buf, ":\"", 2);
     725                 : 
     726             193 :         for (i = 0; i < len; i++) {
     727             147 :                 c = (unsigned char) str[i];
     728             294 :                 if (c < 128 && c != 0x5c /*'\\'*/) {
     729             147 :                         smart_str_appendc(buf, c & 0xff);
     730                 :                 } else {
     731               0 :                         smart_str_appendc(buf, 0x5c /*'\\'*/);
     732               0 :                         smart_str_appendc(buf, hex[(c >> 4) & 0xf]);
     733               0 :                         smart_str_appendc(buf, hex[(c >> 0) & 0xf]);
     734                 :                 }
     735                 :         }
     736                 : 
     737              46 :         smart_str_appendl(buf, "\";", 2);
     738              46 : }
     739                 : /* }}} */
     740                 : 
     741                 : static inline void php_var_serialize_ustr(smart_str *buf, UChar *ustr, int len) /* {{{ */
     742           41763 : {
     743                 :         static const char hex[] = "0123456789abcdef";
     744                 :         UChar c;
     745                 :         int i;
     746                 : 
     747          474004 :         for (i = 0; i < len; i++) {
     748          432241 :                 c = ustr[i];
     749          864478 :                 if (c < 128 && c != 0x5c /*'\\'*/) {
     750          432237 :                         smart_str_appendc(buf, c & 0xff);
     751                 :                 } else {
     752               4 :                         smart_str_appendc(buf, 0x5c /*'\\'*/);
     753               4 :                         smart_str_appendc(buf, hex[(c >> 12) & 0xf]);
     754               4 :                         smart_str_appendc(buf, hex[(c >> 8) & 0xf]);
     755               4 :                         smart_str_appendc(buf, hex[(c >> 4) & 0xf]);
     756               4 :                         smart_str_appendc(buf, hex[(c >> 0) & 0xf]);
     757                 :                 }
     758                 :         }
     759           41763 : }
     760                 : /* }}} */
     761                 : 
     762                 : static inline void php_var_serialize_unicode(smart_str *buf, UChar *ustr, int len) /* {{{ */
     763           41598 : {
     764           41598 :         smart_str_appendl(buf, "U:", 2);
     765           41598 :         smart_str_append_long(buf, len);
     766           41598 :         smart_str_appendl(buf, ":\"", 2);
     767           41598 :         php_var_serialize_ustr(buf, ustr, len);
     768           41598 :         smart_str_appendl(buf, "\";", 2);
     769           41598 : }
     770                 : /* }}} */
     771                 : 
     772                 : static inline zend_bool php_var_serialize_class_name(smart_str *buf, zval *struc TSRMLS_DC) /* {{{ */
     773             135 : {
     774             135 :         PHP_CLASS_ATTRIBUTES;
     775                 : 
     776             135 :         PHP_SET_CLASS_ATTRIBUTES(struc);
     777             135 :         smart_str_appendl(buf, "O:", 2);
     778             135 :         smart_str_append_long(buf, name_len);
     779             135 :         smart_str_appendl(buf, ":\"", 2);
     780             135 :         php_var_serialize_ustr(buf, class_name.u, name_len);
     781             135 :         smart_str_appendl(buf, "\":", 2);
     782             135 :         PHP_CLEANUP_CLASS_ATTRIBUTES();
     783             135 :         return incomplete_class;
     784                 : }
     785                 : /* }}} */
     786                 : 
     787                 : static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_ptr, HashTable *var_hash TSRMLS_DC) /* {{{ */
     788               4 : {
     789                 :         int count;
     790                 :         zend_bool incomplete_class;
     791                 :         zstr star;
     792                 : 
     793               4 :         star.s = "*";
     794                 : 
     795               4 :         incomplete_class = php_var_serialize_class_name(buf, struc TSRMLS_CC);
     796                 :         /* count after serializing name, since php_var_serialize_class_name
     797                 :          * changes the count if the variable is incomplete class */
     798               4 :         count = zend_hash_num_elements(HASH_OF(retval_ptr));
     799               4 :         if (incomplete_class) {
     800               0 :                 --count;
     801                 :         }
     802               4 :         smart_str_append_long(buf, count);
     803               4 :         smart_str_appendl(buf, ":{", 2);
     804                 : 
     805               4 :         if (count > 0) {
     806                 :                 zstr key;
     807                 :                 unsigned int key_len;
     808                 :                 zval **d, **name;
     809                 :                 ulong index;
     810                 :                 HashPosition pos;
     811                 :                 int i;
     812                 :                 zval nval, *nvalp;
     813                 : 
     814               3 :                 ZVAL_NULL(&nval);
     815               3 :                 nvalp = &nval;
     816                 : 
     817               3 :                 zend_hash_internal_pointer_reset_ex(HASH_OF(retval_ptr), &pos);
     818                 : 
     819               8 :                 for (;; zend_hash_move_forward_ex(HASH_OF(retval_ptr), &pos)) {
     820              11 :                         i = zend_hash_get_current_key_ex(HASH_OF(retval_ptr), &key, &key_len, &index, 0, &pos);
     821                 : 
     822              11 :                         if (i == HASH_KEY_NON_EXISTANT) {
     823               3 :                                 break;
     824                 :                         }
     825                 : 
     826               8 :                         if (incomplete_class &&
     827                 :                                 key_len == sizeof(MAGIC_MEMBER) &&
     828                 :                                 ZEND_U_EQUAL(i, key, key_len-1, MAGIC_MEMBER, sizeof(MAGIC_MEMBER)-1)
     829                 :                         ) {
     830               0 :                                 continue;
     831                 :                         }
     832               8 :                         zend_hash_get_current_data_ex(HASH_OF(retval_ptr), (void **) &name, &pos);
     833                 : 
     834               8 :                         if (Z_TYPE_PP(name) != IS_UNICODE) {
     835               0 :                                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize");
     836                 :                                 /* we should still add element even if it's not OK,
     837                 :                                  * since we already wrote the length of the array before */
     838               0 :                                 smart_str_appendl(buf,"N;", 2);
     839               0 :                                 continue;
     840                 :                         }
     841               8 :                         if (zend_u_hash_find(Z_OBJPROP_P(struc), Z_TYPE_PP(name), Z_UNIVAL_PP(name), Z_UNILEN_PP(name) + 1, (void *) &d) == SUCCESS) {
     842               4 :                                 if (Z_TYPE_PP(name) == IS_UNICODE) {
     843               4 :                                         php_var_serialize_unicode(buf, Z_USTRVAL_PP(name), Z_USTRLEN_PP(name));
     844                 :                                 } else {
     845               0 :                                         php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
     846                 :                                 }
     847               4 :                                 php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC);
     848                 :                         } else {
     849                 :                                 zend_class_entry *ce;
     850               4 :                                 ce = zend_get_class_entry(struc TSRMLS_CC);
     851               4 :                                 if (ce) {
     852                 :                                         zstr prot_name, priv_name;
     853                 :                                         int prop_name_length;
     854                 : 
     855                 :                                         do {
     856               4 :                                                 zend_u_mangle_property_name(&priv_name, &prop_name_length, Z_TYPE_PP(name), ce->name, ce->name_length, Z_UNIVAL_PP(name), Z_UNILEN_PP(name), ce->type & ZEND_INTERNAL_CLASS);
     857               4 :                                                 if (zend_u_hash_find(Z_OBJPROP_P(struc), Z_TYPE_PP(name), priv_name, prop_name_length + 1, (void *) &d) == SUCCESS) {
     858               1 :                                                         if (Z_TYPE_PP(name) == IS_UNICODE) {
     859               1 :                                                                 php_var_serialize_unicode(buf, priv_name.u, prop_name_length);
     860                 :                                                         } else {
     861               0 :                                                                 php_var_serialize_string(buf, priv_name.s, prop_name_length);
     862                 :                                                         }
     863               1 :                                                         pefree(priv_name.v, ce->type & ZEND_INTERNAL_CLASS);
     864               1 :                                                         php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC);
     865               1 :                                                         break;
     866                 :                                                 }
     867               3 :                                                 pefree(priv_name.v, ce->type & ZEND_INTERNAL_CLASS);
     868               3 :                                                 zend_u_mangle_property_name(&prot_name, &prop_name_length, Z_TYPE_PP(name), star, 1, Z_UNIVAL_PP(name), Z_UNILEN_PP(name), ce->type & ZEND_INTERNAL_CLASS);
     869               3 :                                                 if (zend_u_hash_find(Z_OBJPROP_P(struc), Z_TYPE_PP(name), prot_name, prop_name_length+1, (void *) &d) == SUCCESS) {
     870               1 :                                                         if (Z_TYPE_PP(name) == IS_UNICODE) {
     871               1 :                                                                 php_var_serialize_unicode(buf, prot_name.u, prop_name_length);
     872                 :                                                         } else {
     873               0 :                                                                 php_var_serialize_string(buf, prot_name.s, prop_name_length);
     874                 :                                                         }
     875               1 :                                                         pefree(prot_name.v, ce->type & ZEND_INTERNAL_CLASS);
     876               1 :                                                         php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC);
     877               1 :                                                         break;
     878                 :                                                 }
     879               2 :                                                 pefree(prot_name.v, ce->type & ZEND_INTERNAL_CLASS);
     880               2 :                                                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "\"%R\" returned as member variable from __sleep() but does not exist", Z_TYPE_PP(name), Z_UNIVAL_PP(name));
     881               2 :                                                 if (Z_TYPE_PP(name) == IS_UNICODE) {
     882               2 :                                                         php_var_serialize_unicode(buf, Z_USTRVAL_PP(name), Z_USTRLEN_PP(name));
     883                 :                                                 } else {
     884               0 :                                                         php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
     885                 :                                                 }
     886               2 :                                                 php_var_serialize_intern(buf, nvalp, var_hash TSRMLS_CC);
     887                 :                                         } while (0);
     888                 :                                 } else {
     889               0 :                                         if (Z_TYPE_PP(name) == IS_UNICODE) {
     890               0 :                                                 php_var_serialize_unicode(buf, Z_USTRVAL_PP(name), Z_USTRLEN_PP(name));
     891                 :                                         } else {
     892               0 :                                                 php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
     893                 :                                         }
     894               0 :                                         php_var_serialize_intern(buf, nvalp, var_hash TSRMLS_CC);
     895                 :                                 }
     896                 :                         }
     897               8 :                 }
     898                 :         }
     899               4 :         smart_str_appendc(buf, '}');
     900               4 : }
     901                 : /* }}} */
     902                 : 
     903                 : static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC) /* {{{ */
     904           29011 : {
     905                 :         int i;
     906                 :         ulong *var_already;
     907                 :         HashTable *myht;
     908                 : 
     909           29011 :         if (var_hash && php_add_var_hash(var_hash, struc, (void *) &var_already TSRMLS_CC) == FAILURE) {
     910           27685 :                 if (Z_ISREF_P(struc)) {
     911              66 :                         smart_str_appendl(buf, "R:", 2);
     912              66 :                         smart_str_append_long(buf, *var_already);
     913              66 :                         smart_str_appendc(buf, ';');
     914              66 :                         return;
     915           27619 :                 } else if (Z_TYPE_P(struc) == IS_OBJECT) {
     916              25 :                         smart_str_appendl(buf, "r:", 2);
     917              25 :                         smart_str_append_long(buf, *var_already);
     918              25 :                         smart_str_appendc(buf, ';');
     919              25 :                         return;
     920                 :                 }
     921                 :         }
     922                 : 
     923           28920 :         switch (Z_TYPE_P(struc)) {
     924                 :                 case IS_BOOL:
     925              50 :                         smart_str_appendl(buf, "b:", 2);
     926              50 :                         smart_str_append_long(buf, Z_LVAL_P(struc));
     927              50 :                         smart_str_appendc(buf, ';');
     928              50 :                         return;
     929                 : 
     930                 :                 case IS_NULL:
     931              92 :                         smart_str_appendl(buf, "N;", 2);
     932              92 :                         return;
     933                 : 
     934                 :                 case IS_LONG:
     935            5107 :                         php_var_serialize_long(buf, Z_LVAL_P(struc));
     936            5107 :                         return;
     937                 : 
     938                 :                 case IS_DOUBLE: {
     939                 :                                 char *s;
     940                 : 
     941              65 :                                 smart_str_appendl(buf, "d:", 2);
     942              65 :                                 s = (char *) safe_emalloc(PG(serialize_precision), 1, MAX_LENGTH_OF_DOUBLE + 1);
     943              65 :                                 php_gcvt(Z_DVAL_P(struc), PG(serialize_precision), '.', 'E', s);
     944              65 :                                 smart_str_appends(buf, s);
     945              65 :                                 smart_str_appendc(buf, ';');
     946              65 :                                 efree(s);
     947              65 :                                 return;
     948                 :                         }
     949                 : 
     950                 :                 case IS_STRING:
     951              34 :                         php_var_serialize_string(buf, Z_STRVAL_P(struc), Z_STRLEN_P(struc));
     952              34 :                         return;
     953                 : 
     954                 :                 case IS_UNICODE:
     955           14784 :                         php_var_serialize_unicode(buf, Z_USTRVAL_P(struc), Z_USTRLEN_P(struc));
     956           14784 :                         return;
     957                 : 
     958                 :                 case IS_OBJECT: {
     959             167 :                                 zval *retval_ptr = NULL;
     960                 :                                 zval fname;
     961                 :                                 int res;
     962             167 :                                 zend_class_entry *ce = NULL;
     963                 : 
     964             167 :                                 if (Z_OBJ_HT_P(struc)->get_class_entry) {
     965             167 :                                         ce = Z_OBJCE_P(struc);
     966                 :                                 }
     967                 : 
     968             167 :                                 if (ce && ce->serialize != NULL) {
     969                 :                                         /* has custom handler */
     970                 :                                         int serialized_type;
     971                 :                                         zstr serialized_data;
     972                 :                                         zend_uint serialized_length;
     973                 : 
     974              31 :                                         serialized_data.v = NULL;
     975              31 :                                         if (ce->serialize(struc, &serialized_type, &serialized_data, &serialized_length, (zend_serialize_data *)var_hash TSRMLS_CC) == SUCCESS) {
     976              26 :                                                 smart_str_appendl(buf, "C:", 2);
     977              26 :                                                 smart_str_append_long(buf, Z_OBJCE_P(struc)->name_length);
     978              26 :                                                 smart_str_appendl(buf, ":\"", 2);
     979              26 :                                                 php_var_serialize_ustr(buf, Z_OBJCE_P(struc)->name.u, Z_OBJCE_P(struc)->name_length);
     980              26 :                                                 smart_str_appendl(buf, "\":", 2);
     981                 : 
     982              26 :                                                 smart_str_append_long(buf, serialized_length);
     983              26 :                                                 if (serialized_type == IS_UNICODE) {
     984               4 :                                                         smart_str_appendl(buf, ":U:{", 4);
     985               4 :                                                         php_var_serialize_ustr(buf, serialized_data.u, serialized_length);
     986              22 :                                                 } else if (serialized_type == IS_STRING) {
     987              22 :                                                         smart_str_appendl(buf, ":{", 2);
     988              22 :                                                         smart_str_appendl(buf, serialized_data.s, serialized_length);
     989                 :                                                 } else {
     990               0 :                                                         smart_str_appendc(buf, 'N');
     991                 :                                                 }
     992              26 :                                                 smart_str_appendc(buf, '}');
     993                 :                                         } else {
     994               5 :                                                 smart_str_appendl(buf, "N;", 2);
     995                 :                                         }
     996              31 :                                         if (serialized_data.v) {
     997              26 :                                                 efree(serialized_data.v);
     998                 :                                         }
     999              31 :                                         return;
    1000                 :                                 }
    1001                 : 
    1002             136 :                                 if (ce && ce != PHP_IC_ENTRY && zend_hash_exists(&ce->function_table, "__sleep", sizeof("__sleep"))) {
    1003              11 :                                         INIT_PZVAL(&fname);
    1004              11 :                                         ZVAL_ASCII_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1, 1);
    1005              11 :                                         res = call_user_function_ex(CG(function_table), &struc, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
    1006              11 :                                         zval_dtor(&fname);
    1007              11 :                                         if (res == SUCCESS && !EG(exception)) {
    1008               5 :                                                 if (retval_ptr) {
    1009               5 :                                                         if (HASH_OF(retval_ptr)) {
    1010               4 :                                                                 php_var_serialize_class(buf, struc, retval_ptr, var_hash TSRMLS_CC);
    1011                 :                                                         } else {
    1012               1 :                                                                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize");
    1013                 :                                                                 /* we should still add element even if it's not OK,
    1014                 :                                                                  * since we already wrote the length of the array before */
    1015               1 :                                                                 smart_str_appendl(buf,"N;", 2);
    1016                 :                                                         }
    1017               5 :                                                         zval_ptr_dtor(&retval_ptr);
    1018                 :                                                 }
    1019               5 :                                                 return;
    1020                 :                                         }
    1021                 :                                 }
    1022                 : 
    1023             131 :                                 if (retval_ptr) {
    1024               0 :                                         zval_ptr_dtor(&retval_ptr);
    1025                 :                                 }
    1026                 :                                 /* fall-through */
    1027                 :                         }
    1028                 :                 case IS_ARRAY: {
    1029            8749 :                         zend_bool incomplete_class = 0;
    1030            8749 :                         if (Z_TYPE_P(struc) == IS_ARRAY) {
    1031            8618 :                                 smart_str_appendl(buf, "a:", 2);
    1032            8618 :                                 myht = HASH_OF(struc);
    1033                 :                         } else {
    1034             131 :                                 incomplete_class = php_var_serialize_class_name(buf, struc TSRMLS_CC);
    1035             131 :                                 myht = Z_OBJPROP_P(struc);
    1036                 :                         }
    1037                 :                         /* count after serializing name, since php_var_serialize_class_name
    1038                 :                          * changes the count if the variable is incomplete class */
    1039            8749 :                         i = myht ? zend_hash_num_elements(myht) : 0;
    1040            8749 :                         if (i > 0 && incomplete_class) {
    1041               2 :                                 --i;
    1042                 :                         }
    1043            8749 :                         smart_str_append_long(buf, i);
    1044            8749 :                         smart_str_appendl(buf, ":{", 2);
    1045            8749 :                         if (i > 0) {
    1046                 :                                 zstr key;
    1047                 :                                 zval **data;
    1048                 :                                 ulong index;
    1049                 :                                 uint key_len;
    1050                 :                                 HashPosition pos;
    1051                 : 
    1052            8687 :                                 zend_hash_internal_pointer_reset_ex(myht, &pos);
    1053           28342 :                                 for (;; zend_hash_move_forward_ex(myht, &pos)) {
    1054           37029 :                                         i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
    1055           37029 :                                         if (i == HASH_KEY_NON_EXISTANT) {
    1056            8687 :                                                 break;
    1057                 :                                         }
    1058                 : 
    1059           28342 :                                         if (incomplete_class &&
    1060                 :                                                 key_len == sizeof(MAGIC_MEMBER) &&
    1061                 :                                                 ZEND_U_EQUAL(i, key, key_len - 1, MAGIC_MEMBER, sizeof(MAGIC_MEMBER) - 1)
    1062                 :                                         ) {
    1063               0 :                                                 continue;
    1064                 :                                         }
    1065                 : 
    1066           28342 :                                         switch (i) {
    1067                 :                                                 case HASH_KEY_IS_LONG:
    1068            1524 :                                                         php_var_serialize_long(buf, index);
    1069            1524 :                                                         break;
    1070                 :                                                 case HASH_KEY_IS_STRING:
    1071              12 :                                                         php_var_serialize_string(buf, key.s, key_len - 1);
    1072              12 :                                                         break;
    1073                 :                                                 case HASH_KEY_IS_UNICODE:
    1074           26806 :                                                         php_var_serialize_unicode(buf, key.u, key_len - 1);
    1075                 :                                                         break;
    1076                 :                                         }
    1077                 : 
    1078                 :                                         /* we should still add element even if it's not OK,
    1079                 :                                          * since we already wrote the length of the array before */
    1080           28342 :                                         if (zend_hash_get_current_data_ex(myht, (void **) &data, &pos) != SUCCESS
    1081                 :                                                 || !data
    1082                 :                                                 || data == &struc
    1083                 :                                                 || (Z_TYPE_PP(data) == IS_ARRAY && Z_ARRVAL_PP(data)->nApplyCount > 1)
    1084                 :                                         ) {
    1085               0 :                                                 smart_str_appendl(buf, "N;", 2);
    1086                 :                                         } else {
    1087           28342 :                                                 if (Z_TYPE_PP(data) == IS_ARRAY) {
    1088            8453 :                                                         Z_ARRVAL_PP(data)->nApplyCount++;
    1089                 :                                                 }
    1090           28342 :                                                 php_var_serialize_intern(buf, *data, var_hash TSRMLS_CC);
    1091           28342 :                                                 if (Z_TYPE_PP(data) == IS_ARRAY) {
    1092            8453 :                                                         Z_ARRVAL_PP(data)->nApplyCount--;
    1093                 :                                                 }
    1094                 :                                         }
    1095           28342 :                                 }
    1096                 :                         }
    1097            8749 :                         smart_str_appendc(buf, '}');
    1098            8749 :                         return;
    1099                 :                 }
    1100                 :                 default:
    1101               3 :                         smart_str_appendl(buf, "i:0;", 4);
    1102               3 :                         return;
    1103                 :         }
    1104                 : }
    1105                 : /* }}} */
    1106                 : 
    1107                 : PHPAPI void php_var_serialize(smart_str *buf, zval **struc, HashTable *var_hash TSRMLS_DC) /* {{{ */
    1108             661 : {
    1109             661 :         php_var_serialize_intern(buf, *struc, var_hash TSRMLS_CC);
    1110             661 :         smart_str_0(buf);
    1111             661 : }
    1112                 : /* }}} */
    1113                 : 
    1114                 : /* {{{ proto string serialize(mixed variable) U
    1115                 :    Returns a string representation of variable (which can later be unserialized) */
    1116                 : PHP_FUNCTION(serialize)
    1117             255 : {
    1118                 :         zval **struc;
    1119                 :         php_serialize_data_t var_hash;
    1120             255 :         smart_str buf = {0};
    1121                 : 
    1122             255 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &struc) == FAILURE) {
    1123               2 :                 return;
    1124                 :         }
    1125                 : 
    1126             253 :         Z_TYPE_P(return_value) = IS_STRING;
    1127             253 :         Z_STRVAL_P(return_value) = NULL;
    1128             253 :         Z_STRLEN_P(return_value) = 0;
    1129                 : 
    1130             253 :         PHP_VAR_SERIALIZE_INIT(var_hash);
    1131             253 :         php_var_serialize(&buf, struc, &var_hash TSRMLS_CC);
    1132             253 :         PHP_VAR_SERIALIZE_DESTROY(var_hash);
    1133                 : 
    1134             253 :         if (buf.c) {
    1135             253 :                 RETVAL_ASCII_STRINGL(buf.c, buf.len, 0);
    1136             253 :                 smart_str_free(&buf);
    1137                 :         } else {
    1138               0 :                 RETURN_NULL();
    1139                 :         }
    1140                 : }
    1141                 : /* }}} */
    1142                 : 
    1143                 : /* {{{ proto mixed unserialize(string variable_representation) U
    1144                 :    Takes a string representation of variable and recreates it */
    1145                 : PHP_FUNCTION(unserialize)
    1146             216 : {
    1147             216 :         char *buf = NULL;
    1148                 :         int buf_len;
    1149                 :         const unsigned char *p;
    1150                 :         php_unserialize_data_t var_hash;
    1151                 : 
    1152             216 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&", &buf, &buf_len, UG(ascii_conv)) == FAILURE) {
    1153               2 :                 RETURN_FALSE;
    1154                 :         }
    1155                 : 
    1156             214 :         if (buf_len == 0) {
    1157               0 :                 RETURN_FALSE;
    1158                 :         }
    1159                 : 
    1160             214 :         p = (const unsigned char*) buf;
    1161             214 :         PHP_VAR_UNSERIALIZE_INIT(var_hash);
    1162             214 :         if (!php_var_unserialize(&return_value, &p, p + buf_len, &var_hash TSRMLS_CC)) {
    1163              15 :                 PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
    1164              15 :                 zval_dtor(return_value);
    1165              15 :                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len);
    1166              15 :                 RETURN_FALSE;
    1167                 :         }
    1168             199 :         PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
    1169                 : }
    1170                 : /* }}} */
    1171                 : 
    1172                 : /* {{{ proto int memory_get_usage([real_usage]) U
    1173                 :    Returns the allocated by PHP memory */
    1174               3 : PHP_FUNCTION(memory_get_usage) {
    1175               3 :         zend_bool real_usage = 0;
    1176                 : 
    1177               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &real_usage) == FAILURE) {
    1178               0 :                 RETURN_FALSE;
    1179                 :         }
    1180                 : 
    1181               3 :         RETURN_LONG(zend_memory_usage(real_usage TSRMLS_CC));
    1182                 : }
    1183                 : /* }}} */
    1184                 : 
    1185                 : /* {{{ proto int memory_get_peak_usage([real_usage]) U
    1186                 :    Returns the peak allocated by PHP memory */
    1187               1 : PHP_FUNCTION(memory_get_peak_usage) {
    1188               1 :         zend_bool real_usage = 0;
    1189                 : 
    1190               1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &real_usage) == FAILURE) {
    1191               0 :                 RETURN_FALSE;
    1192                 :         }
    1193                 : 
    1194               1 :         RETURN_LONG(zend_memory_peak_usage(real_usage TSRMLS_CC));
    1195                 : }
    1196                 : /* }}} */
    1197                 : 
    1198                 : /*
    1199                 :  * Local variables:
    1200                 :  * tab-width: 4
    1201                 :  * c-basic-offset: 4
    1202                 :  * End:
    1203                 :  * vim600: sw=4 ts=4 fdm=marker
    1204                 :  * vim<600: sw=4 ts=4
    1205                 :  */

Generated by: LTP GCOV extension version 1.5

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

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