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

LCOV - code coverage report
Current view: top level - ext/standard - var.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 478 513 93.2 %
Date: 2016-09-18 Functions: 25 27 92.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2016 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$ */
      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 "zend_smart_str.h"
      32             : #include "basic_functions.h"
      33             : #include "php_incomplete_class.h"
      34             : /* }}} */
      35             : 
      36             : struct php_serialize_data {
      37             :         HashTable ht;
      38             :         uint32_t n;
      39             : };
      40             : 
      41             : #define COMMON (is_ref ? "&" : "")
      42             : 
      43       65619 : static void php_array_element_dump(zval *zv, zend_ulong index, zend_string *key, int level) /* {{{ */
      44             : {
      45       65619 :         if (key == NULL) { /* numeric key */
      46       46000 :                 php_printf("%*c[" ZEND_LONG_FMT "]=>\n", level + 1, ' ', index);
      47             :         } else { /* string key */
      48       19619 :                 php_printf("%*c[\"", level + 1, ' ');
      49       19619 :                 PHPWRITE(ZSTR_VAL(key), ZSTR_LEN(key));
      50       19619 :                 php_printf("\"]=>\n");
      51             :         }
      52       65619 :         php_var_dump(zv, level + 2);
      53       65619 : }
      54             : /* }}} */
      55             : 
      56        7271 : static void php_object_property_dump(zval *zv, zend_ulong index, zend_string *key, int level) /* {{{ */
      57             : {
      58             :         const char *prop_name, *class_name;
      59             : 
      60        7271 :         if (key == NULL) { /* numeric key */
      61         116 :                 php_printf("%*c[" ZEND_LONG_FMT "]=>\n", level + 1, ' ', index);
      62             :         } else { /* string key */
      63        7155 :                 int unmangle = zend_unmangle_property_name(key, &class_name, &prop_name);
      64        7155 :                 php_printf("%*c[", level + 1, ' ');
      65             : 
      66        8210 :                 if (class_name && unmangle == SUCCESS) {
      67        1055 :                         if (class_name[0] == '*') {
      68         328 :                                 php_printf("\"%s\":protected", prop_name);
      69             :                         } else {
      70         727 :                                 php_printf("\"%s\":\"%s\":private", prop_name, class_name);
      71             :                         }
      72             :                 } else {
      73        6100 :                         php_printf("\"");
      74        6100 :                         PHPWRITE(ZSTR_VAL(key), ZSTR_LEN(key));
      75        6100 :                         php_printf("\"");
      76             :                 }
      77        7155 :                 ZEND_PUTS("]=>\n");
      78             :         }
      79        7271 :         php_var_dump(zv, level + 2);
      80        7271 : }
      81             : /* }}} */
      82             : 
      83      228433 : PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */
      84             : {
      85             :         HashTable *myht;
      86             :         zend_string *class_name;
      87             :         int is_temp;
      88      228433 :         int is_ref = 0;
      89             :         zend_ulong num;
      90             :         zend_string *key;
      91             :         zval *val;
      92             :         uint32_t count;
      93             : 
      94      228433 :         if (level > 1) {
      95       72890 :                 php_printf("%*c", level - 1, ' ');
      96             :         }
      97             : 
      98             : again:
      99      229534 :         switch (Z_TYPE_P(struc)) {
     100             :                 case IS_FALSE:
     101       30779 :                         php_printf("%sbool(false)\n", COMMON);
     102       30779 :                         break;
     103             :                 case IS_TRUE:
     104       15325 :                         php_printf("%sbool(true)\n", COMMON);
     105       15325 :                         break;
     106             :                 case IS_NULL:
     107       13940 :                         php_printf("%sNULL\n", COMMON);
     108       13940 :                         break;
     109             :                 case IS_LONG:
     110       66461 :                         php_printf("%sint(" ZEND_LONG_FMT ")\n", COMMON, Z_LVAL_P(struc));
     111       66460 :                         break;
     112             :                 case IS_DOUBLE:
     113        6320 :                         php_printf("%sfloat(%.*G)\n", COMMON, (int) EG(precision), Z_DVAL_P(struc));
     114        6320 :                         break;
     115             :                 case IS_STRING:
     116       68483 :                         php_printf("%sstring(%zd) \"", COMMON, Z_STRLEN_P(struc));
     117       68483 :                         PHPWRITE(Z_STRVAL_P(struc), Z_STRLEN_P(struc));
     118       68483 :                         PUTS("\"\n");
     119       68483 :                         break;
     120             :                 case IS_ARRAY:
     121       22178 :                         myht = Z_ARRVAL_P(struc);
     122       22178 :                         if (level > 1 && ZEND_HASH_APPLY_PROTECTION(myht) && ++myht->u.v.nApplyCount > 1) {
     123          65 :                                 PUTS("*RECURSION*\n");
     124          65 :                                 --myht->u.v.nApplyCount;
     125          65 :                                 return;
     126             :                         }
     127       22113 :                         count = zend_array_count(myht);
     128       22113 :                         php_printf("%sarray(%d) {\n", COMMON, count);
     129       22113 :                         is_temp = 0;
     130             : 
     131      225252 :                         ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
     132       65619 :                                 php_array_element_dump(val, num, key, level);
     133             :                         } ZEND_HASH_FOREACH_END();
     134       22113 :                         if (level > 1 && ZEND_HASH_APPLY_PROTECTION(myht)) {
     135        5096 :                                 --myht->u.v.nApplyCount;
     136             :                         }
     137       22113 :                         if (is_temp) {
     138           0 :                                 zend_hash_destroy(myht);
     139           0 :                                 efree(myht);
     140             :                         }
     141       22113 :                         if (level > 1) {
     142        5096 :                                 php_printf("%*c", level-1, ' ');
     143             :                         }
     144       22113 :                         PUTS("}\n");
     145       22113 :                         break;
     146             :                 case IS_OBJECT:
     147        4048 :                         if (Z_OBJ_APPLY_COUNT_P(struc) > 0) {
     148          62 :                                 PUTS("*RECURSION*\n");
     149          62 :                                 return;
     150             :                         }
     151        3986 :                         Z_OBJ_INC_APPLY_COUNT_P(struc);
     152             : 
     153        3986 :                         myht = Z_OBJDEBUG_P(struc, is_temp);
     154        3975 :                         class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc));
     155        3975 :                         php_printf("%sobject(%s)#%d (%d) {\n", COMMON, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0);
     156             :                         zend_string_release(class_name);
     157             : 
     158        3975 :                         if (myht) {
     159             :                                 zend_ulong num;
     160             :                                 zend_string *key;
     161             :                                 zval *val;
     162             : 
     163       25914 :                                 ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
     164        7271 :                                         php_object_property_dump(val, num, key, level);
     165             :                                 } ZEND_HASH_FOREACH_END();
     166        3975 :                                 if (is_temp) {
     167         596 :                                         zend_hash_destroy(myht);
     168         596 :                                         efree(myht);
     169             :                                 }
     170             :                         }
     171        3975 :                         if (level > 1) {
     172        1393 :                                 php_printf("%*c", level-1, ' ');
     173             :                         }
     174        3975 :                         PUTS("}\n");
     175        3975 :                         Z_OBJ_DEC_APPLY_COUNT_P(struc);
     176        3975 :                         break;
     177             :                 case IS_RESOURCE: {
     178         899 :                         const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(struc));
     179         899 :                         php_printf("%sresource(%d) of type (%s)\n", COMMON, Z_RES_P(struc)->handle, type_name ? type_name : "Unknown");
     180         899 :                         break;
     181             :                 }
     182             :                 case IS_REFERENCE:
     183             :                         //??? hide references with refcount==1 (for compatibility)
     184        1101 :                         if (Z_REFCOUNT_P(struc) > 1) {
     185         824 :                                 is_ref = 1;
     186             :                         }
     187        1101 :                         struc = Z_REFVAL_P(struc);
     188        1101 :                         goto again;
     189             :                         break;
     190             :                 default:
     191           0 :                         php_printf("%sUNKNOWN:0\n", COMMON);
     192             :                         break;
     193             :         }
     194             : }
     195             : /* }}} */
     196             : 
     197             : /* {{{ proto void var_dump(mixed var)
     198             :    Dumps a string representation of variable to output */
     199      153456 : PHP_FUNCTION(var_dump)
     200             : {
     201             :         zval *args;
     202             :         int argc;
     203             :         int     i;
     204             : 
     205      153456 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
     206           1 :                 return;
     207             :         }
     208             : 
     209      308986 :         for (i = 0; i < argc; i++) {
     210      155543 :                 php_var_dump(&args[i], 1);
     211             :         }
     212             : }
     213             : /* }}} */
     214             : 
     215         169 : static void zval_array_element_dump(zval *zv, zend_ulong index, zend_string *key, int level) /* {{{ */
     216             : {
     217         169 :         if (key == NULL) { /* numeric key */
     218          59 :                 php_printf("%*c[" ZEND_LONG_FMT "]=>\n", level + 1, ' ', index);
     219             :         } else { /* string key */
     220         110 :                 php_printf("%*c[\"", level + 1, ' ');
     221         110 :                 PHPWRITE(ZSTR_VAL(key), ZSTR_LEN(key));
     222         110 :                 php_printf("\"]=>\n");
     223             :         }
     224         169 :         php_debug_zval_dump(zv, level + 2);
     225         169 : }
     226             : /* }}} */
     227             : 
     228         242 : static void zval_object_property_dump(zval *zv, zend_ulong index, zend_string *key, int level) /* {{{ */
     229             : {
     230             :         const char *prop_name, *class_name;
     231             : 
     232         242 :         if (key == NULL) { /* numeric key */
     233           0 :                 php_printf("%*c[" ZEND_LONG_FMT "]=>\n", level + 1, ' ', index);
     234             :         } else { /* string key */
     235         242 :                 zend_unmangle_property_name(key, &class_name, &prop_name);
     236         242 :                 php_printf("%*c[", level + 1, ' ');
     237             : 
     238         242 :                 if (class_name) {
     239          78 :                         if (class_name[0] == '*') {
     240          39 :                                 php_printf("\"%s\":protected", prop_name);
     241             :                         } else {
     242          39 :                                 php_printf("\"%s\":\"%s\":private", prop_name, class_name);
     243             :                         }
     244             :                 } else {
     245         164 :                         php_printf("\"%s\"", prop_name);
     246             :                 }
     247         242 :                 ZEND_PUTS("]=>\n");
     248             :         }
     249         242 :         php_debug_zval_dump(zv, level + 2);
     250         242 : }
     251             : /* }}} */
     252             : 
     253         670 : PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */
     254             : {
     255         670 :         HashTable *myht = NULL;
     256             :         zend_string *class_name;
     257         670 :         int is_temp = 0;
     258         670 :         int is_ref = 0;
     259             :         zend_ulong index;
     260             :         zend_string *key;
     261             :         zval *val;
     262             :         uint32_t count;
     263             : 
     264         670 :         if (level > 1) {
     265         411 :                 php_printf("%*c", level - 1, ' ');
     266             :         }
     267             : 
     268             : again:
     269         696 :         switch (Z_TYPE_P(struc)) {
     270             :         case IS_FALSE:
     271           4 :                 php_printf("%sbool(false)\n", COMMON);
     272           4 :                 break;
     273             :         case IS_TRUE:
     274           3 :                 php_printf("%sbool(true)\n", COMMON);
     275           3 :                 break;
     276             :         case IS_NULL:
     277          22 :                 php_printf("%sNULL\n", COMMON);
     278          22 :                 break;
     279             :         case IS_LONG:
     280         374 :                 php_printf("%sint(" ZEND_LONG_FMT ")\n", COMMON, Z_LVAL_P(struc));
     281         374 :                 break;
     282             :         case IS_DOUBLE:
     283          19 :                 php_printf("%sfloat(%.*G)\n", COMMON, (int) EG(precision), Z_DVAL_P(struc));
     284          19 :                 break;
     285             :         case IS_STRING:
     286          82 :                 php_printf("%sstring(%zd) \"", COMMON, Z_STRLEN_P(struc));
     287          82 :                 PHPWRITE(Z_STRVAL_P(struc), Z_STRLEN_P(struc));
     288         126 :                 php_printf("\" refcount(%u)\n", Z_REFCOUNTED_P(struc) ? Z_REFCOUNT_P(struc) : 1);
     289          82 :                 break;
     290             :         case IS_ARRAY:
     291          96 :                 myht = Z_ARRVAL_P(struc);
     292          96 :                 if (level > 1 && ZEND_HASH_APPLY_PROTECTION(myht) && myht->u.v.nApplyCount++ > 1) {
     293           2 :                         myht->u.v.nApplyCount--;
     294           2 :                         PUTS("*RECURSION*\n");
     295           2 :                         return;
     296             :                 }
     297          94 :                 count = zend_array_count(myht);
     298         188 :                 php_printf("%sarray(%d) refcount(%u){\n", COMMON, count, Z_REFCOUNTED_P(struc) ? Z_REFCOUNT_P(struc) : 1);
     299         607 :                 ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) {
     300         169 :                         zval_array_element_dump(val, index, key, level);
     301             :                 } ZEND_HASH_FOREACH_END();
     302          94 :                 if (level > 1 && ZEND_HASH_APPLY_PROTECTION(myht)) {
     303          59 :                         myht->u.v.nApplyCount--;
     304             :                 }
     305          94 :                 if (is_temp) {
     306           0 :                         zend_hash_destroy(myht);
     307           0 :                         efree(myht);
     308             :                 }
     309          94 :                 if (level > 1) {
     310          59 :                         php_printf("%*c", level - 1, ' ');
     311             :                 }
     312          94 :                 PUTS("}\n");
     313          94 :                 break;
     314             :         case IS_OBJECT:
     315          69 :                 myht = Z_OBJDEBUG_P(struc, is_temp);
     316          69 :                 if (myht) {
     317          69 :                         if (myht->u.v.nApplyCount > 1) {
     318          24 :                                 PUTS("*RECURSION*\n");
     319          24 :                                 return;
     320             :                         } else {
     321          45 :                                 myht->u.v.nApplyCount++;
     322             :                         }
     323             :                 }
     324          45 :                 class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc));
     325          45 :                 php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0, Z_REFCOUNT_P(struc));
     326             :                 zend_string_release(class_name);
     327          45 :                 if (myht) {
     328         771 :                         ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) {
     329         242 :                                 zval_object_property_dump(val, index, key, level);
     330             :                         } ZEND_HASH_FOREACH_END();
     331          45 :                         myht->u.v.nApplyCount--;
     332          45 :                         if (is_temp) {
     333           1 :                                 zend_hash_destroy(myht);
     334           1 :                                 efree(myht);
     335             :                         }
     336             :                 }
     337          45 :                 if (level > 1) {
     338          34 :                         php_printf("%*c", level - 1, ' ');
     339             :                 }
     340          45 :                 PUTS("}\n");
     341          45 :                 break;
     342             :         case IS_RESOURCE: {
     343           1 :                 const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(struc));
     344           1 :                 php_printf("%sresource(%d) of type (%s) refcount(%u)\n", COMMON, Z_RES_P(struc)->handle, type_name ? type_name : "Unknown", Z_REFCOUNT_P(struc));
     345           1 :                 break;
     346             :         }
     347             :         case IS_REFERENCE:
     348             :                 //??? hide references with refcount==1 (for compatibility)
     349          26 :                 if (Z_REFCOUNT_P(struc) > 1) {
     350          20 :                         is_ref = 1;
     351             :                 }
     352          26 :                 struc = Z_REFVAL_P(struc);
     353          26 :                 goto again;
     354             :         default:
     355           0 :                 php_printf("%sUNKNOWN:0\n", COMMON);
     356             :                 break;
     357             :         }
     358             : }
     359             : /* }}} */
     360             : 
     361             : /* {{{ proto void debug_zval_dump(mixed var)
     362             :    Dumps a string representation of an internal zend value to output. */
     363         165 : PHP_FUNCTION(debug_zval_dump)
     364             : {
     365             :         zval *args;
     366             :         int argc;
     367             :         int     i;
     368             : 
     369         165 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
     370           1 :                 return;
     371             :         }
     372             : 
     373         423 :         for (i = 0; i < argc; i++) {
     374         259 :                 php_debug_zval_dump(&args[i], 1);
     375             :         }
     376             : }
     377             : /* }}} */
     378             : 
     379             : #define buffer_append_spaces(buf, num_spaces) \
     380             :         do { \
     381             :                 char *tmp_spaces; \
     382             :                 size_t tmp_spaces_len; \
     383             :                 tmp_spaces_len = spprintf(&tmp_spaces, 0,"%*c", num_spaces, ' '); \
     384             :                 smart_str_appendl(buf, tmp_spaces, tmp_spaces_len); \
     385             :                 efree(tmp_spaces); \
     386             :         } while(0);
     387             : 
     388        1182 : static void php_array_element_export(zval *zv, zend_ulong index, zend_string *key, int level, smart_str *buf) /* {{{ */
     389             : {
     390        1182 :         if (key == NULL) { /* numeric key */
     391        2106 :                 buffer_append_spaces(buf, level+1);
     392        1053 :                 smart_str_append_long(buf, (zend_long) index);
     393             :                 smart_str_appendl(buf, " => ", 4);
     394             : 
     395             :         } else { /* string key */
     396             :                 zend_string *tmp_str;
     397         129 :                 zend_string *ckey = php_addcslashes(key, 0, "'\\", 2);
     398         129 :                 tmp_str = php_str_to_str(ZSTR_VAL(ckey), ZSTR_LEN(ckey), "\0", 1, "' . \"\\0\" . '", 12);
     399             : 
     400         258 :                 buffer_append_spaces(buf, level + 1);
     401             : 
     402             :                 smart_str_appendc(buf, '\'');
     403             :                 smart_str_append(buf, tmp_str);
     404             :                 smart_str_appendl(buf, "' => ", 5);
     405             : 
     406             :                 zend_string_free(ckey);
     407             :                 zend_string_free(tmp_str);
     408             :         }
     409        1182 :         php_var_export_ex(zv, level + 2, buf);
     410             : 
     411             :         smart_str_appendc(buf, ',');
     412             :         smart_str_appendc(buf, '\n');
     413        1182 : }
     414             : /* }}} */
     415             : 
     416         395 : static void php_object_element_export(zval *zv, zend_ulong index, zend_string *key, int level, smart_str *buf) /* {{{ */
     417             : {
     418         790 :         buffer_append_spaces(buf, level + 2);
     419         395 :         if (key != NULL) {
     420             :                 const char *class_name, *prop_name;
     421             :                 size_t prop_name_len;
     422             :                 zend_string *pname_esc;
     423             : 
     424         392 :                 zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_name_len);
     425         784 :                 pname_esc = php_addcslashes(zend_string_init(prop_name, prop_name_len, 0), 1, "'\\", 2);
     426             : 
     427             :                 smart_str_appendc(buf, '\'');
     428             :                 smart_str_append(buf, pname_esc);
     429             :                 smart_str_appendc(buf, '\'');
     430             :                 zend_string_release(pname_esc);
     431             :         } else {
     432           3 :                 smart_str_append_long(buf, (zend_long) index);
     433             :         }
     434             :         smart_str_appendl(buf, " => ", 4);
     435         395 :         php_var_export_ex(zv, level + 2, buf);
     436             :         smart_str_appendc(buf, ',');
     437             :         smart_str_appendc(buf, '\n');
     438         395 : }
     439             : /* }}} */
     440             : 
     441        3266 : PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */
     442             : {
     443             :         HashTable *myht;
     444             :         char tmp_str[PHP_DOUBLE_MAX_LENGTH];
     445             :         zend_string *ztmp, *ztmp2;
     446             :         zend_ulong index;
     447             :         zend_string *key;
     448             :         zval *val;
     449             : 
     450             : again:
     451        3266 :         switch (Z_TYPE_P(struc)) {
     452             :                 case IS_FALSE:
     453             :                         smart_str_appendl(buf, "false", 5);
     454          39 :                         break;
     455             :                 case IS_TRUE:
     456             :                         smart_str_appendl(buf, "true", 4);
     457         114 :                         break;
     458             :                 case IS_NULL:
     459             :                         smart_str_appendl(buf, "NULL", 4);
     460         179 :                         break;
     461             :                 case IS_LONG:
     462         653 :                         smart_str_append_long(buf, Z_LVAL_P(struc));
     463         653 :                         break;
     464             :                 case IS_DOUBLE:
     465         206 :                         php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', tmp_str);
     466         206 :                         smart_str_appends(buf, tmp_str);
     467             :                         /* Without a decimal point, PHP treats a number literal as an int.
     468             :                          * This check even works for scientific notation, because the
     469             :                          * mantissa always contains a decimal point.
     470             :                          * We need to check for finiteness, because INF, -INF and NAN
     471             :                          * must not have a decimal point added.
     472             :                          */
     473         206 :                         if (zend_finite(Z_DVAL_P(struc)) && NULL == strchr(tmp_str, '.')) {
     474             :                                 smart_str_appendl(buf, ".0", 2);
     475             :                         }
     476         206 :                         break;
     477             :                 case IS_STRING:
     478        1315 :                         ztmp = php_addcslashes(Z_STR_P(struc), 0, "'\\", 2);
     479        1315 :                         ztmp2 = php_str_to_str(ZSTR_VAL(ztmp), ZSTR_LEN(ztmp), "\0", 1, "' . \"\\0\" . '", 12);
     480             : 
     481             :                         smart_str_appendc(buf, '\'');
     482             :                         smart_str_append(buf, ztmp2);
     483             :                         smart_str_appendc(buf, '\'');
     484             : 
     485             :                         zend_string_free(ztmp);
     486             :                         zend_string_free(ztmp2);
     487        1315 :                         break;
     488             :                 case IS_ARRAY:
     489         451 :                         myht = Z_ARRVAL_P(struc);
     490         451 :                         if (ZEND_HASH_APPLY_PROTECTION(myht) && myht->u.v.nApplyCount++ > 0) {
     491           1 :                                 myht->u.v.nApplyCount--;
     492             :                                 smart_str_appendl(buf, "NULL", 4);
     493           1 :                                 zend_error(E_WARNING, "var_export does not handle circular references");
     494           1 :                                 return;
     495             :                         }
     496         450 :                         if (level > 1) {
     497             :                                 smart_str_appendc(buf, '\n');
     498          80 :                                 buffer_append_spaces(buf, level - 1);
     499             :                         }
     500             :                         smart_str_appendl(buf, "array (\n", 8);
     501        4017 :                         ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) {
     502        1182 :                                 php_array_element_export(val, index, key, level, buf);
     503             :                         } ZEND_HASH_FOREACH_END();
     504         450 :                         if (ZEND_HASH_APPLY_PROTECTION(myht)) {
     505         450 :                                 myht->u.v.nApplyCount--;
     506             :                         }
     507         450 :                         if (level > 1) {
     508          80 :                                 buffer_append_spaces(buf, level - 1);
     509             :                         }
     510             :                         smart_str_appendc(buf, ')');
     511             : 
     512         450 :                         break;
     513             : 
     514             :                 case IS_OBJECT:
     515         247 :                         myht = Z_OBJPROP_P(struc);
     516         247 :                         if (myht) {
     517         247 :                                 if (myht->u.v.nApplyCount > 0) {
     518             :                                         smart_str_appendl(buf, "NULL", 4);
     519           1 :                                         zend_error(E_WARNING, "var_export does not handle circular references");
     520           1 :                                         return;
     521             :                                 } else {
     522         246 :                                         myht->u.v.nApplyCount++;
     523             :                                 }
     524             :                         }
     525         246 :                         if (level > 1) {
     526             :                                 smart_str_appendc(buf, '\n');
     527         284 :                                 buffer_append_spaces(buf, level - 1);
     528             :                         }
     529             : 
     530         246 :                         smart_str_append(buf, Z_OBJCE_P(struc)->name);
     531             :                         smart_str_appendl(buf, "::__set_state(array(\n", 21);
     532             : 
     533         246 :                         if (myht) {
     534        1431 :                                 ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) {
     535         395 :                                         php_object_element_export(val, index, key, level, buf);
     536             :                                 } ZEND_HASH_FOREACH_END();
     537         246 :                                 myht->u.v.nApplyCount--;
     538             :                         }
     539         246 :                         if (level > 1) {
     540         284 :                                 buffer_append_spaces(buf, level - 1);
     541             :                         }
     542             :                         smart_str_appendl(buf, "))", 2);
     543             : 
     544         246 :                         break;
     545             :                 case IS_REFERENCE:
     546          62 :                         struc = Z_REFVAL_P(struc);
     547          62 :                         goto again;
     548             :                         break;
     549             :                 default:
     550             :                         smart_str_appendl(buf, "NULL", 4);
     551             :                         break;
     552             :         }
     553             : }
     554             : /* }}} */
     555             : 
     556             : /* FOR BC reasons, this will always perform and then print */
     557           0 : PHPAPI void php_var_export(zval *struc, int level) /* {{{ */
     558             : {
     559           0 :         smart_str buf = {0};
     560           0 :         php_var_export_ex(struc, level, &buf);
     561             :         smart_str_0(&buf);
     562           0 :         PHPWRITE(ZSTR_VAL(buf.s), ZSTR_LEN(buf.s));
     563             :         smart_str_free(&buf);
     564           0 : }
     565             : /* }}} */
     566             : 
     567             : /* {{{ proto mixed var_export(mixed var [, bool return])
     568             :    Outputs or returns a string representation of a variable */
     569        1631 : PHP_FUNCTION(var_export)
     570             : {
     571             :         zval *var;
     572        1631 :         zend_bool return_output = 0;
     573        1631 :         smart_str buf = {0};
     574             : 
     575        1631 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &var, &return_output) == FAILURE) {
     576           4 :                 return;
     577             :         }
     578             : 
     579        1627 :         php_var_export_ex(var, 1, &buf);
     580             :         smart_str_0 (&buf);
     581             : 
     582        1627 :         if (return_output) {
     583        1219 :                 RETURN_NEW_STR(buf.s);
     584             :         } else {
     585         408 :                 PHPWRITE(ZSTR_VAL(buf.s), ZSTR_LEN(buf.s));
     586             :                 smart_str_free(&buf);
     587             :         }
     588             : }
     589             : /* }}} */
     590             : 
     591             : static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_data_t var_hash);
     592             : 
     593      261287 : static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var) /* {{{ */
     594             : {
     595             :         zval *zv;
     596             :         zend_ulong key;
     597      261287 :         zend_bool is_ref = Z_ISREF_P(var);
     598             : 
     599      261287 :         data->n += 1;
     600             : 
     601      522063 :         if (!is_ref && Z_TYPE_P(var) != IS_OBJECT) {
     602      107880 :                 return 0;
     603             :         }
     604             : 
     605             :         /* References to objects are treated as if the reference didn't exist */
     606      153918 :         if (is_ref && Z_TYPE_P(Z_REFVAL_P(var)) == IS_OBJECT) {
     607          16 :                 var = Z_REFVAL_P(var);
     608             :         }
     609             : 
     610             :         /* Index for the variable is stored using the numeric value of the pointer to
     611             :          * the zend_refcounted struct */
     612      153407 :         key = (zend_ulong) (zend_uintptr_t) Z_COUNTED_P(var);
     613      153407 :         zv = zend_hash_index_find(&data->ht, key);
     614             : 
     615      153407 :         if (zv) {
     616             :                 /* References are only counted once, undo the data->n increment above */
     617       10345 :                 if (is_ref) {
     618         261 :                         data->n -= 1;
     619             :                 }
     620             : 
     621       10345 :                 return Z_LVAL_P(zv);
     622             :         } else {
     623             :                 zval zv_n;
     624      143062 :                 ZVAL_LONG(&zv_n, data->n);
     625      143062 :                 zend_hash_index_add_new(&data->ht, key, &zv_n);
     626             : 
     627             :                 /* Additionally to the index, we also store the variable, to ensure that it is
     628             :                  * not destroyed during serialization and its pointer reused. The variable is
     629             :                  * stored at the numeric value of the pointer + 1, which cannot be the location
     630             :                  * of another zend_refcounted structure. */
     631      143062 :                 zend_hash_index_add_new(&data->ht, key + 1, var);
     632             :                 Z_ADDREF_P(var);
     633             : 
     634      143062 :                 return 0;
     635             :         }
     636             : }
     637             : /* }}} */
     638             : 
     639      151971 : static inline void php_var_serialize_long(smart_str *buf, zend_long val) /* {{{ */
     640             : {
     641             :         smart_str_appendl(buf, "i:", 2);
     642             :         smart_str_append_long(buf, val);
     643             :         smart_str_appendc(buf, ';');
     644      151971 : }
     645             : /* }}} */
     646             : 
     647       44309 : static inline void php_var_serialize_string(smart_str *buf, char *str, size_t len) /* {{{ */
     648             : {
     649             :         smart_str_appendl(buf, "s:", 2);
     650             :         smart_str_append_unsigned(buf, len);
     651             :         smart_str_appendl(buf, ":\"", 2);
     652             :         smart_str_appendl(buf, str, len);
     653             :         smart_str_appendl(buf, "\";", 2);
     654       44309 : }
     655             : /* }}} */
     656             : 
     657      142746 : static inline zend_bool php_var_serialize_class_name(smart_str *buf, zval *struc) /* {{{ */
     658             : {
     659      142746 :         PHP_CLASS_ATTRIBUTES;
     660             : 
     661      285490 :         PHP_SET_CLASS_ATTRIBUTES(struc);
     662             :         smart_str_appendl(buf, "O:", 2);
     663      142746 :         smart_str_append_unsigned(buf, ZSTR_LEN(class_name));
     664             :         smart_str_appendl(buf, ":\"", 2);
     665             :         smart_str_append(buf, class_name);
     666             :         smart_str_appendl(buf, "\":", 2);
     667             :         PHP_CLEANUP_CLASS_ATTRIBUTES();
     668      142746 :         return incomplete_class;
     669             : }
     670             : /* }}} */
     671             : 
     672           9 : static HashTable *php_var_serialize_collect_names(HashTable *src, uint32_t count, zend_bool incomplete) /* {{{ */ {
     673             :         zval *val;
     674             :         HashTable *ht;
     675             :         zend_string *key, *name;
     676             : 
     677           9 :         ALLOC_HASHTABLE(ht);
     678           9 :         zend_hash_init(ht, count, NULL, NULL, 0);
     679          49 :         ZEND_HASH_FOREACH_STR_KEY_VAL(src, key, val) {
     680          20 :                 if (incomplete && strcmp(ZSTR_VAL(key), MAGIC_MEMBER) == 0) {
     681           0 :                         continue;
     682             :                 }
     683          20 :                 if (Z_TYPE_P(val) != IS_STRING) {
     684           1 :                         php_error_docref(NULL, E_NOTICE,
     685             :                                         "__sleep should return an array only containing the names of instance-variables to serialize.");
     686             :                 }
     687          20 :                 name = zval_get_string(val);
     688          20 :                 if (zend_hash_exists(ht, name)) {
     689           1 :                         php_error_docref(NULL, E_NOTICE,
     690             :                                         "\"%s\" is returned from __sleep multiple times", ZSTR_VAL(name));
     691             :                         zend_string_release(name);
     692           1 :                         continue;
     693             :                 }
     694          19 :                 zend_hash_add_empty_element(ht, name);
     695             :                 zend_string_release(name);
     696             :         } ZEND_HASH_FOREACH_END();
     697             : 
     698           9 :         return ht;
     699             : }
     700             : /* }}} */
     701             : 
     702          11 : static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_ptr, php_serialize_data_t var_hash) /* {{{ */
     703             : {
     704             :         uint32_t count;
     705             :         zend_bool incomplete_class;
     706             :         HashTable *ht;
     707             : 
     708          11 :         incomplete_class = php_var_serialize_class_name(buf, struc);
     709             :         /* count after serializing name, since php_var_serialize_class_name
     710             :          * changes the count if the variable is incomplete class */
     711          11 :         if (Z_TYPE_P(retval_ptr) == IS_ARRAY) {
     712          11 :                 ht = Z_ARRVAL_P(retval_ptr);
     713          11 :                 count = zend_array_count(ht);
     714           0 :         } else if (Z_TYPE_P(retval_ptr) == IS_OBJECT) {
     715           0 :                 ht = Z_OBJPROP_P(retval_ptr);
     716           0 :                 count = zend_array_count(ht);
     717           0 :                 if (incomplete_class) {
     718           0 :                         --count;
     719             :                 }
     720             :         } else {
     721           0 :                 count = 0;
     722           0 :                 ht = NULL;
     723             :         }
     724             : 
     725          11 :         if (count > 0) {
     726             :                 zval *d;
     727             :                 zval nval, *nvalp;
     728             :                 zend_string *name;
     729             :                 HashTable *names, *propers;
     730             : 
     731           9 :                 names = php_var_serialize_collect_names(ht, count, incomplete_class);
     732             : 
     733           9 :                 smart_str_append_unsigned(buf, zend_hash_num_elements(names));
     734             :                 smart_str_appendl(buf, ":{", 2);
     735             : 
     736           9 :                 ZVAL_NULL(&nval);
     737           9 :                 nvalp = &nval;
     738           9 :                 propers = Z_OBJPROP_P(struc);
     739             : 
     740          47 :                 ZEND_HASH_FOREACH_STR_KEY(names, name) {
     741          19 :                         if ((d = zend_hash_find(propers, name)) != NULL) {
     742          10 :                                 if (Z_TYPE_P(d) == IS_INDIRECT) {
     743           9 :                                         d = Z_INDIRECT_P(d);
     744           9 :                                         if (Z_TYPE_P(d) == IS_UNDEF) {
     745           0 :                                                 continue;
     746             :                                         }
     747             :                                 }
     748          10 :                                 php_var_serialize_string(buf, ZSTR_VAL(name), ZSTR_LEN(name));
     749          10 :                                 php_var_serialize_intern(buf, d, var_hash);
     750             :                         } else {
     751           9 :                                 zend_class_entry *ce = Z_OBJ_P(struc)->ce;
     752           9 :                                 if (ce) {
     753             :                                         zend_string *prot_name, *priv_name;
     754             : 
     755             :                                         do {
     756          27 :                                                 priv_name = zend_mangle_property_name(
     757          18 :                                                                 ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
     758           9 :                                                 if ((d = zend_hash_find(propers, priv_name)) != NULL) {
     759           2 :                                                         if (Z_TYPE_P(d) == IS_INDIRECT) {
     760           2 :                                                                 d = Z_INDIRECT_P(d);
     761           2 :                                                                 if (Z_ISUNDEF_P(d)) {
     762           0 :                                                                         break;
     763             :                                                                 }
     764             :                                                         }
     765           2 :                                                         php_var_serialize_string(buf, ZSTR_VAL(priv_name), ZSTR_LEN(priv_name));
     766             :                                                         zend_string_free(priv_name);
     767           2 :                                                         php_var_serialize_intern(buf, d, var_hash);
     768           2 :                                                         break;
     769             :                                                 }
     770             :                                                 zend_string_free(priv_name);
     771           7 :                                                 prot_name = zend_mangle_property_name(
     772             :                                                                 "*", 1, ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
     773           7 :                                                 if ((d = zend_hash_find(propers, prot_name)) != NULL) {
     774           2 :                                                         if (Z_TYPE_P(d) == IS_INDIRECT) {
     775           2 :                                                                 d = Z_INDIRECT_P(d);
     776           2 :                                                                 if (Z_TYPE_P(d) == IS_UNDEF) {
     777             :                                                                         zend_string_free(prot_name);
     778           0 :                                                                         break;
     779             :                                                                 }
     780             :                                                         }
     781           2 :                                                         php_var_serialize_string(buf, ZSTR_VAL(prot_name), ZSTR_LEN(prot_name));
     782             :                                                         zend_string_free(prot_name);
     783           2 :                                                         php_var_serialize_intern(buf, d, var_hash);
     784           2 :                                                         break;
     785             :                                                 }
     786             :                                                 zend_string_free(prot_name);
     787           5 :                                                 php_var_serialize_string(buf, ZSTR_VAL(name), ZSTR_LEN(name));
     788           5 :                                                 php_var_serialize_intern(buf, nvalp, var_hash);
     789           5 :                                                 php_error_docref(NULL, E_NOTICE,
     790             :                                                                 "\"%s\" returned as member variable from __sleep() but does not exist", ZSTR_VAL(name));
     791             :                                         } while (0);
     792             :                                 } else {
     793           0 :                                         php_var_serialize_string(buf, ZSTR_VAL(name), ZSTR_LEN(name));
     794           0 :                                         php_var_serialize_intern(buf, nvalp, var_hash);
     795             :                                 }
     796             :                         }
     797             :                 } ZEND_HASH_FOREACH_END();
     798             :                 smart_str_appendc(buf, '}');
     799             : 
     800           9 :                 zend_hash_destroy(names);
     801           9 :                 FREE_HASHTABLE(names);
     802             :         } else {
     803             :                 smart_str_appendl(buf, "0:{}", 4);
     804             :         }
     805          11 : }
     806             : /* }}} */
     807             : 
     808      261288 : static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_data_t var_hash) /* {{{ */
     809             : {
     810             :         zend_long var_already;
     811             :         HashTable *myht;
     812             : 
     813      261288 :         if (EG(exception)) {
     814           1 :                 return;
     815             :         }
     816             : 
     817      261287 :         if (var_hash && (var_already = php_add_var_hash(var_hash, struc))) {
     818       10345 :                 if (Z_ISREF_P(struc)) {
     819             :                         smart_str_appendl(buf, "R:", 2);
     820             :                         smart_str_append_long(buf, var_already);
     821             :                         smart_str_appendc(buf, ';');
     822         261 :                         return;
     823       10084 :                 } else if (Z_TYPE_P(struc) == IS_OBJECT) {
     824             :                         smart_str_appendl(buf, "r:", 2);
     825             :                         smart_str_append_long(buf, var_already);
     826             :                         smart_str_appendc(buf, ';');
     827       10084 :                         return;
     828             :                 }
     829             :         }
     830             : 
     831             : again:
     832      251192 :         switch (Z_TYPE_P(struc)) {
     833             :                 case IS_FALSE:
     834             :                         smart_str_appendl(buf, "b:0;", 4);
     835          46 :                         return;
     836             : 
     837             :                 case IS_TRUE:
     838             :                         smart_str_appendl(buf, "b:1;", 4);
     839          64 :                         return;
     840             : 
     841             :                 case IS_NULL:
     842             :                         smart_str_appendl(buf, "N;", 2);
     843       10107 :                         return;
     844             : 
     845             :                 case IS_LONG:
     846        6900 :                         php_var_serialize_long(buf, Z_LVAL_P(struc));
     847        6900 :                         return;
     848             : 
     849             :                 case IS_DOUBLE: {
     850             :                         char tmp_str[PHP_DOUBLE_MAX_LENGTH];
     851             :                         smart_str_appendl(buf, "d:", 2);
     852         105 :                         php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', tmp_str);
     853         105 :                         smart_str_appends(buf, tmp_str);
     854             :                         smart_str_appendc(buf, ';');
     855         105 :                         return;
     856             :                 }
     857             : 
     858             :                 case IS_STRING:
     859       15489 :                         php_var_serialize_string(buf, Z_STRVAL_P(struc), Z_STRLEN_P(struc));
     860       15489 :                         return;
     861             : 
     862             :                 case IS_OBJECT: {
     863             :                                 zval retval;
     864             :                                 zval fname;
     865             :                                 int res;
     866      142816 :                                 zend_class_entry *ce = Z_OBJCE_P(struc);
     867             : 
     868      142816 :                                 if (ce->serialize != NULL) {
     869             :                                         /* has custom handler */
     870          62 :                                         unsigned char *serialized_data = NULL;
     871             :                                         size_t serialized_length;
     872             : 
     873          62 :                                         if (ce->serialize(struc, &serialized_data, &serialized_length, (zend_serialize_data *)var_hash) == SUCCESS) {
     874             :                                                 smart_str_appendl(buf, "C:", 2);
     875          54 :                                                 smart_str_append_unsigned(buf, ZSTR_LEN(Z_OBJCE_P(struc)->name));
     876             :                                                 smart_str_appendl(buf, ":\"", 2);
     877          54 :                                                 smart_str_append(buf, Z_OBJCE_P(struc)->name);
     878             :                                                 smart_str_appendl(buf, "\":", 2);
     879             : 
     880          54 :                                                 smart_str_append_unsigned(buf, serialized_length);
     881             :                                                 smart_str_appendl(buf, ":{", 2);
     882          54 :                                                 smart_str_appendl(buf, (char *) serialized_data, serialized_length);
     883             :                                                 smart_str_appendc(buf, '}');
     884             :                                         } else {
     885             :                                                 smart_str_appendl(buf, "N;", 2);
     886             :                                         }
     887          62 :                                         if (serialized_data) {
     888          54 :                                                 efree(serialized_data);
     889             :                                         }
     890          62 :                                         return;
     891             :                                 }
     892             : 
     893      142754 :                                 if (ce != PHP_IC_ENTRY && zend_hash_str_exists(&ce->function_table, "__sleep", sizeof("__sleep")-1)) {
     894          38 :                                         ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1);
     895          19 :                                         BG(serialize_lock)++;
     896          19 :                                         res = call_user_function_ex(CG(function_table), struc, &fname, &retval, 0, 0, 1, NULL);
     897          19 :                                         BG(serialize_lock)--;
     898             :                                         zval_dtor(&fname);
     899             : 
     900          19 :                                         if (EG(exception)) {
     901           7 :                                                 zval_ptr_dtor(&retval);
     902           7 :                                                 return;
     903             :                                         }
     904             : 
     905          12 :                                         if (res == SUCCESS) {
     906          12 :                                                 if (Z_TYPE(retval) != IS_UNDEF) {
     907          13 :                                                         if (HASH_OF(&retval)) {
     908          11 :                                                                 php_var_serialize_class(buf, struc, &retval, var_hash);
     909             :                                                         } else {
     910           1 :                                                                 php_error_docref(NULL, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize");
     911             :                                                                 /* we should still add element even if it's not OK,
     912             :                                                                  * since we already wrote the length of the array before */
     913             :                                                                 smart_str_appendl(buf,"N;", 2);
     914             :                                                         }
     915          12 :                                                         zval_ptr_dtor(&retval);
     916             :                                                 }
     917          12 :                                                 return;
     918             :                                         }
     919           0 :                                         zval_ptr_dtor(&retval);
     920             :                                 }
     921             : 
     922             :                                 /* fall-through */
     923             :                         }
     924             :                 case IS_ARRAY: {
     925             :                         uint32_t i;
     926      218145 :                         zend_bool incomplete_class = 0;
     927      218145 :                         if (Z_TYPE_P(struc) == IS_ARRAY) {
     928             :                                 smart_str_appendl(buf, "a:", 2);
     929       75410 :                                 myht = Z_ARRVAL_P(struc);
     930       75410 :                                 i = zend_array_count(myht);
     931             :                         } else {
     932      142735 :                                 incomplete_class = php_var_serialize_class_name(buf, struc);
     933      142735 :                                 myht = Z_OBJPROP_P(struc);
     934             :                                 /* count after serializing name, since php_var_serialize_class_name
     935             :                                  * changes the count if the variable is incomplete class */
     936      142735 :                                 i = zend_array_count(myht);
     937      142735 :                                 if (i > 0 && incomplete_class) {
     938           2 :                                         --i;
     939             :                                 }
     940             :                         }
     941      218145 :                         smart_str_append_unsigned(buf, i);
     942             :                         smart_str_appendl(buf, ":{", 2);
     943      218145 :                         if (i > 0) {
     944             :                                 zend_string *key;
     945             :                                 zval *data;
     946             :                                 zend_ulong index;
     947             : 
     948      597573 :                                 ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, data) {
     949             : 
     950      173872 :                                         if (incomplete_class && strcmp(ZSTR_VAL(key), MAGIC_MEMBER) == 0) {
     951           0 :                                                 continue;
     952             :                                         }
     953             : 
     954      173872 :                                         if (!key) {
     955      145071 :                                                 php_var_serialize_long(buf, index);
     956             :                                         } else {
     957       28801 :                                                 php_var_serialize_string(buf, ZSTR_VAL(key), ZSTR_LEN(key));
     958             :                                         }
     959             : 
     960      174569 :                                         if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1) {
     961         193 :                                                 data = Z_REFVAL_P(data);
     962             :                                         }
     963             : 
     964             :                                         /* we should still add element even if it's not OK,
     965             :                                          * since we already wrote the length of the array before */
     966      365489 :                                         if ((Z_TYPE_P(data) == IS_ARRAY && Z_TYPE_P(struc) == IS_ARRAY && Z_ARR_P(data) == Z_ARR_P(struc))
     967        8872 :                                                 || (Z_TYPE_P(data) == IS_ARRAY && Z_ARRVAL_P(data)->u.v.nApplyCount > 1)
     968             :                                         ) {
     969             :                                                 smart_str_appendl(buf, "N;", 2);
     970             :                                         } else {
     971      173871 :                                                 if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data))) {
     972        8872 :                                                         Z_ARRVAL_P(data)->u.v.nApplyCount++;
     973             :                                                 }
     974      173871 :                                                 php_var_serialize_intern(buf, data, var_hash);
     975      173871 :                                                 if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data))) {
     976        8872 :                                                         Z_ARRVAL_P(data)->u.v.nApplyCount--;
     977             :                                                 }
     978             :                                         }
     979             :                                 } ZEND_HASH_FOREACH_END();
     980             :                         }
     981             :                         smart_str_appendc(buf, '}');
     982      218145 :                         return;
     983             :                 }
     984             :                 case IS_REFERENCE:
     985         250 :                         struc = Z_REFVAL_P(struc);
     986         250 :                         goto again;
     987             :                 default:
     988             :                         smart_str_appendl(buf, "i:0;", 4);
     989           5 :                         return;
     990             :         }
     991             : }
     992             : /* }}} */
     993             : 
     994       87398 : PHPAPI void php_var_serialize(smart_str *buf, zval *struc, php_serialize_data_t *data) /* {{{ */
     995             : {
     996       87398 :         php_var_serialize_intern(buf, struc, *data);
     997             :         smart_str_0(buf);
     998       87398 : }
     999             : /* }}} */
    1000             : 
    1001       67288 : PHPAPI php_serialize_data_t php_var_serialize_init() {
    1002             :         struct php_serialize_data *d;
    1003             :         /* fprintf(stderr, "SERIALIZE_INIT      == lock: %u, level: %u\n", BG(serialize_lock), BG(serialize).level); */
    1004      134527 :         if (BG(serialize_lock) || !BG(serialize).level) {
    1005       67239 :                 d = emalloc(sizeof(struct php_serialize_data));
    1006       67239 :                 zend_hash_init(&d->ht, 16, NULL, ZVAL_PTR_DTOR, 0);
    1007       67239 :                 d->n = 0;
    1008       67239 :                 if (!BG(serialize_lock)) {
    1009       67237 :                         BG(serialize).data = d;
    1010       67237 :                         BG(serialize).level = 1;
    1011             :                 }
    1012             :         } else {
    1013          49 :                 d = BG(serialize).data;
    1014          49 :                 ++BG(serialize).level;
    1015             :         }
    1016       67288 :         return d;
    1017             : }
    1018             : 
    1019       67288 : PHPAPI void php_var_serialize_destroy(php_serialize_data_t d) {
    1020             :         /* fprintf(stderr, "SERIALIZE_DESTROY   == lock: %u, level: %u\n", BG(serialize_lock), BG(serialize).level); */
    1021       67288 :         if (BG(serialize_lock) || BG(serialize).level == 1) {
    1022       67239 :                 zend_hash_destroy(&d->ht);
    1023       67239 :                 efree(d);
    1024             :         }
    1025       67288 :         if (!BG(serialize_lock) && !--BG(serialize).level) {
    1026       67237 :                 BG(serialize).data = NULL;
    1027             :         }
    1028       67288 : }
    1029             : 
    1030             : /* {{{ proto string serialize(mixed variable)
    1031             :    Returns a string representation of variable (which can later be unserialized) */
    1032       66754 : PHP_FUNCTION(serialize)
    1033             : {
    1034             :         zval *struc;
    1035             :         php_serialize_data_t var_hash;
    1036       66754 :         smart_str buf = {0};
    1037             : 
    1038       66754 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &struc) == FAILURE) {
    1039           2 :                 return;
    1040             :         }
    1041             : 
    1042       66752 :         PHP_VAR_SERIALIZE_INIT(var_hash);
    1043       66752 :         php_var_serialize(&buf, struc, &var_hash);
    1044       66752 :         PHP_VAR_SERIALIZE_DESTROY(var_hash);
    1045             : 
    1046       66752 :         if (EG(exception)) {
    1047             :                 smart_str_free(&buf);
    1048          13 :                 RETURN_FALSE;
    1049             :         }
    1050             : 
    1051       66739 :         if (buf.s) {
    1052       66739 :                 RETURN_NEW_STR(buf.s);
    1053             :         } else {
    1054           0 :                 RETURN_NULL();
    1055             :         }
    1056             : }
    1057             : /* }}} */
    1058             : 
    1059             : /* {{{ proto mixed unserialize(string variable_representation[, array allowed_classes])
    1060             :    Takes a string representation of variable and recreates it */
    1061       66616 : PHP_FUNCTION(unserialize)
    1062             : {
    1063       66616 :         char *buf = NULL;
    1064             :         size_t buf_len;
    1065             :         const unsigned char *p;
    1066             :         php_unserialize_data_t var_hash;
    1067       66616 :         zval *options = NULL, *classes = NULL;
    1068       66616 :         HashTable *class_hash = NULL, *prev_class_hash;
    1069             : 
    1070       66616 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|a", &buf, &buf_len, &options) == FAILURE) {
    1071           2 :                 RETURN_FALSE;
    1072             :         }
    1073             : 
    1074       66614 :         if (buf_len == 0) {
    1075           0 :                 RETURN_FALSE;
    1076             :         }
    1077             : 
    1078       66614 :         p = (const unsigned char*) buf;
    1079       66614 :         PHP_VAR_UNSERIALIZE_INIT(var_hash);
    1080             : 
    1081       66614 :         prev_class_hash = php_var_unserialize_get_allowed_classes(var_hash);
    1082       66614 :         if (options != NULL) {
    1083          13 :                 classes = zend_hash_str_find(Z_ARRVAL_P(options), "allowed_classes", sizeof("allowed_classes")-1);
    1084          35 :                 if (classes && Z_TYPE_P(classes) != IS_ARRAY && Z_TYPE_P(classes) != IS_TRUE && Z_TYPE_P(classes) != IS_FALSE) {
    1085           3 :                         php_error_docref(NULL, E_WARNING, "allowed_classes option should be array or boolean");
    1086           3 :                         PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
    1087           3 :                         RETURN_FALSE;
    1088             :                 }
    1089             : 
    1090          20 :                 if(classes && (Z_TYPE_P(classes) == IS_ARRAY || !zend_is_true(classes))) {
    1091           9 :                         ALLOC_HASHTABLE(class_hash);
    1092           9 :                         zend_hash_init(class_hash, (Z_TYPE_P(classes) == IS_ARRAY)?zend_hash_num_elements(Z_ARRVAL_P(classes)):0, NULL, NULL, 0);
    1093             :                 }
    1094          19 :                 if(class_hash && Z_TYPE_P(classes) == IS_ARRAY) {
    1095             :                         zval *entry;
    1096             :                         zend_string *lcname;
    1097             : 
    1098          26 :                         ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(classes), entry) {
    1099           9 :                                 convert_to_string_ex(entry);
    1100           9 :                                 lcname = zend_string_tolower(Z_STR_P(entry));
    1101           9 :                                 zend_hash_add_empty_element(class_hash, lcname);
    1102             :                         zend_string_release(lcname);
    1103             :                         } ZEND_HASH_FOREACH_END();
    1104             :                 }
    1105          10 :                 php_var_unserialize_set_allowed_classes(var_hash, class_hash);
    1106             :         }
    1107             : 
    1108       66611 :         if (!php_var_unserialize(return_value, &p, p + buf_len, &var_hash)) {
    1109          61 :                 zval_ptr_dtor(return_value);
    1110          61 :                 if (!EG(exception)) {
    1111          39 :                         php_error_docref(NULL, E_NOTICE, "Error at offset " ZEND_LONG_FMT " of %zd bytes",
    1112             :                                 (zend_long)((char*)p - buf), buf_len);
    1113             :                 }
    1114          61 :                 RETVAL_FALSE;
    1115             :         } else {
    1116             :                 /* We should keep an reference to return_value to prevent it from being dtor
    1117             :                    in case nesting calls to unserialize */
    1118       66550 :                 var_push_dtor(&var_hash, return_value);
    1119             : 
    1120             :                 /* Ensure return value is a value */
    1121       66550 :                 if (Z_ISREF_P(return_value)) {
    1122             :                         zend_unwrap_reference(return_value);
    1123             :                 }
    1124             :         }
    1125             : 
    1126       66611 :         if (class_hash) {
    1127           9 :                 zend_hash_destroy(class_hash);
    1128           9 :                 FREE_HASHTABLE(class_hash);
    1129             :         }
    1130             : 
    1131             :         /* Reset to previous allowed_classes in case this is a nested call */
    1132       66611 :         php_var_unserialize_set_allowed_classes(var_hash, prev_class_hash);
    1133       66611 :         PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
    1134             : }
    1135             : /* }}} */
    1136             : 
    1137             : /* {{{ proto int memory_get_usage([bool real_usage])
    1138             :    Returns the allocated by PHP memory */
    1139        1016 : PHP_FUNCTION(memory_get_usage) {
    1140        1016 :         zend_bool real_usage = 0;
    1141             : 
    1142        1016 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &real_usage) == FAILURE) {
    1143           0 :                 RETURN_FALSE;
    1144             :         }
    1145             : 
    1146        1016 :         RETURN_LONG(zend_memory_usage(real_usage));
    1147             : }
    1148             : /* }}} */
    1149             : 
    1150             : /* {{{ proto int memory_get_peak_usage([bool real_usage])
    1151             :    Returns the peak allocated by PHP memory */
    1152           0 : PHP_FUNCTION(memory_get_peak_usage) {
    1153           0 :         zend_bool real_usage = 0;
    1154             : 
    1155           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &real_usage) == FAILURE) {
    1156           0 :                 RETURN_FALSE;
    1157             :         }
    1158             : 
    1159           0 :         RETURN_LONG(zend_memory_peak_usage(real_usage));
    1160             : }
    1161             : /* }}} */
    1162             : 
    1163             : /*
    1164             :  * Local variables:
    1165             :  * tab-width: 4
    1166             :  * c-basic-offset: 4
    1167             :  * End:
    1168             :  * vim600: sw=4 ts=4 fdm=marker
    1169             :  * vim<600: sw=4 ts=4
    1170             :  */

Generated by: LCOV version 1.10

Generated at Sun, 18 Sep 2016 08:20:18 +0000 (6 days ago)

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