--- embedaddon/php/ext/standard/var.c 2012/02/21 23:48:02 1.1 +++ embedaddon/php/ext/standard/var.c 2013/07/22 01:32:05 1.1.1.3 @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2012 The PHP Group | + | Copyright (c) 1997-2013 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -12,13 +12,13 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Jani Lehtimäki | + | Authors: Jani Lehtimäki | | Thies C. Arntzen | | Sascha Schumann | +----------------------------------------------------------------------+ */ -/* $Id: var.c,v 1.1 2012/02/21 23:48:02 misho Exp $ */ +/* $Id: var.c,v 1.1.1.3 2013/07/22 01:32:05 misho Exp $ */ /* {{{ includes */ @@ -56,7 +56,7 @@ static int php_array_element_dump(zval **zv TSRMLS_DC, static int php_object_property_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ { int level; - char *prop_name, *class_name; + const char *prop_name, *class_name; level = va_arg(args, int); @@ -87,7 +87,7 @@ static int php_object_property_dump(zval **zv TSRMLS_D PHPAPI void php_var_dump(zval **struc, int level TSRMLS_DC) /* {{{ */ { HashTable *myht; - char *class_name; + const char *class_name; zend_uint class_name_len; int (*php_element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*); int is_temp; @@ -133,9 +133,13 @@ PHPAPI void php_var_dump(zval **struc, int level TSRML return; } - Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC); - php_printf("%sobject(%s)#%d (%d) {\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0); - efree(class_name); + if (Z_OBJ_HANDLER(**struc, get_class_name)) { + Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC); + php_printf("%sobject(%s)#%d (%d) {\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0); + efree((char*)class_name); + } else { + php_printf("%sobject(unknown class)#%d (%d) {\n", COMMON, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0); + } php_element_dump_func = php_object_property_dump; head_done: if (myht) { @@ -152,9 +156,7 @@ head_done: PUTS("}\n"); break; case IS_RESOURCE: { - char *type_name; - - type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(struc) TSRMLS_CC); + const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(struc) TSRMLS_CC); php_printf("%sresource(%ld) of type (%s)\n", COMMON, Z_LVAL_PP(struc), type_name ? type_name : "Unknown"); break; } @@ -211,7 +213,7 @@ static int zval_array_element_dump(zval **zv TSRMLS_DC static int zval_object_property_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ { int level; - char *prop_name, *class_name; + const char *prop_name, *class_name; level = va_arg(args, int); @@ -240,7 +242,7 @@ static int zval_object_property_dump(zval **zv TSRMLS_ PHPAPI void php_debug_zval_dump(zval **struc, int level TSRMLS_DC) /* {{{ */ { HashTable *myht = NULL; - char *class_name; + const char *class_name; zend_uint class_name_len; int (*zval_element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*); int is_temp = 0; @@ -282,13 +284,9 @@ PHPAPI void php_debug_zval_dump(zval **struc, int leve PUTS("*RECURSION*\n"); return; } - if (Z_OBJ_HANDLER_PP(struc, get_class_name)) { - Z_OBJ_HANDLER_PP(struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC); - php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0, Z_REFCOUNT_PP(struc)); - efree(class_name); - } else { - php_printf("%sobject(unknown class)#%d (%d) refcount(%u){\n", COMMON, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0, Z_REFCOUNT_PP(struc)); - } + Z_OBJ_HANDLER_PP(struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC); + php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0, Z_REFCOUNT_PP(struc)); + efree((char*)class_name); zval_element_dump_func = zval_object_property_dump; head_done: if (myht) { @@ -304,9 +302,7 @@ head_done: PUTS("}\n"); break; case IS_RESOURCE: { - char *type_name; - - type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(struc) TSRMLS_CC); + const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(struc) TSRMLS_CC); php_printf("%sresource(%ld) of type (%s) refcount(%u)\n", COMMON, Z_LVAL_PP(struc), type_name ? type_name : "Unknown", Z_REFCOUNT_PP(struc)); break; } @@ -357,6 +353,7 @@ static int php_array_element_export(zval **zv TSRMLS_D buffer_append_spaces(buf, level+1); smart_str_append_long(buf, (long) hash_key->h); smart_str_appendl(buf, " => ", 4); + } else { /* string key */ char *key, *tmp_str; int key_len, tmp_len; @@ -376,7 +373,7 @@ static int php_array_element_export(zval **zv TSRMLS_D smart_str_appendc(buf, ','); smart_str_appendc(buf, '\n'); - + return 0; } /* }}} */ @@ -391,9 +388,9 @@ static int php_object_element_export(zval **zv TSRMLS_ buffer_append_spaces(buf, level + 2); if (hash_key->nKeyLength != 0) { - char *class_name, /* ignored, but must be passed to unmangle */ - *pname, - *pname_esc; + const char *class_name; /* ignored, but must be passed to unmangle */ + const char *pname; + char *pname_esc; int pname_esc_len; zend_unmangle_property_name(hash_key->arKey, hash_key->nKeyLength - 1, @@ -406,14 +403,12 @@ static int php_object_element_export(zval **zv TSRMLS_ smart_str_appendc(buf, '\''); efree(pname_esc); } else { - smart_str_append_long(buf, hash_key->h); + smart_str_append_long(buf, (long) hash_key->h); } - smart_str_appendl(buf, " => ", 4); php_var_export_ex(zv, level + 2, buf TSRMLS_CC); smart_str_appendc(buf, ','); smart_str_appendc(buf, '\n'); - return 0; } /* }}} */ @@ -423,16 +418,16 @@ PHPAPI void php_var_export_ex(zval **struc, int level, HashTable *myht; char *tmp_str, *tmp_str2; int tmp_len, tmp_len2; - char *class_name; + const char *class_name; zend_uint class_name_len; switch (Z_TYPE_PP(struc)) { case IS_BOOL: - if (Z_LVAL_PP(struc)) { - smart_str_appendl(buf, "true", 4); - } else { - smart_str_appendl(buf, "false", 5); - } + if (Z_LVAL_PP(struc)) { + smart_str_appendl(buf, "true", 4); + } else { + smart_str_appendl(buf, "false", 5); + } break; case IS_NULL: smart_str_appendl(buf, "NULL", 4); @@ -458,6 +453,11 @@ PHPAPI void php_var_export_ex(zval **struc, int level, break; case IS_ARRAY: myht = Z_ARRVAL_PP(struc); + if(myht && myht->nApplyCount > 0){ + smart_str_appendl(buf, "NULL", 4); + zend_error(E_WARNING, "var_export does not handle circular references"); + return; + } if (level > 1) { smart_str_appendc(buf, '\n'); buffer_append_spaces(buf, level - 1); @@ -469,10 +469,16 @@ PHPAPI void php_var_export_ex(zval **struc, int level, buffer_append_spaces(buf, level - 1); } smart_str_appendc(buf, ')'); - + break; + case IS_OBJECT: myht = Z_OBJPROP_PP(struc); + if(myht && myht->nApplyCount > 0){ + smart_str_appendl(buf, "NULL", 4); + zend_error(E_WARNING, "var_export does not handle circular references"); + return; + } if (level > 1) { smart_str_appendc(buf, '\n'); buffer_append_spaces(buf, level - 1); @@ -482,9 +488,9 @@ PHPAPI void php_var_export_ex(zval **struc, int level, smart_str_appendl(buf, class_name, class_name_len); smart_str_appendl(buf, "::__set_state(array(\n", 21); - efree(class_name); + efree((char*)class_name); if (myht) { - zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) php_object_element_export, 2, level, buf); + zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) php_object_element_export, 1, level, buf); } if (level > 1) { buffer_append_spaces(buf, level - 1); @@ -510,6 +516,7 @@ PHPAPI void php_var_export(zval **struc, int level TSR } /* }}} */ + /* {{{ proto mixed var_export(mixed var [, bool return]) Outputs or returns a string representation of a variable */ PHP_FUNCTION(var_export) @@ -544,12 +551,9 @@ static inline int php_add_var_hash(HashTable *var_hash /* relies on "(long)" being a perfect hash function for data pointers, * however the actual identity of an object has had to be determined - * by its object handle and the class entry since 5.0. */ + * by its object handle since 5.0. */ if ((Z_TYPE_P(var) == IS_OBJECT) && Z_OBJ_HT_P(var)->get_class_entry) { - p = smart_str_print_long(id + sizeof(id) - 1, - (((size_t)Z_OBJCE_P(var) << 5) - | ((size_t)Z_OBJCE_P(var) >> (sizeof(long) * 8 - 5))) - + (long) Z_OBJ_HANDLE_P(var)); + p = smart_str_print_long(id + sizeof(id) - 1, (long) Z_OBJ_HANDLE_P(var)); *(--p) = 'O'; len = id + sizeof(id) - 1 - p; } else { @@ -564,12 +568,18 @@ static inline int php_add_var_hash(HashTable *var_hash var_no = -1; zend_hash_next_index_insert(var_hash, &var_no, sizeof(var_no), NULL); } +#if 0 + fprintf(stderr, "- had var (%d): %lu\n", Z_TYPE_P(var), **(ulong**)var_old); +#endif return FAILURE; } /* +1 because otherwise hash will think we are trying to store NULL pointer */ var_no = zend_hash_num_elements(var_hash) + 1; zend_hash_add(var_hash, p, len, &var_no, sizeof(var_no), NULL); +#if 0 + fprintf(stderr, "+ add var (%d): %lu\n", Z_TYPE_P(var), var_no); +#endif return SUCCESS; } /* }}} */ @@ -629,6 +639,7 @@ static void php_var_serialize_class(smart_str *buf, zv HashPosition pos; int i; zval nval, *nvalp; + HashTable *propers; ZVAL_NULL(&nval); nvalp = &nval; @@ -654,7 +665,8 @@ static void php_var_serialize_class(smart_str *buf, zv smart_str_appendl(buf,"N;", 2); continue; } - if (zend_hash_find(Z_OBJPROP_P(struc), Z_STRVAL_PP(name), Z_STRLEN_PP(name) + 1, (void *) &d) == SUCCESS) { + propers = Z_OBJPROP_P(struc); + if (zend_hash_find(propers, Z_STRVAL_PP(name), Z_STRLEN_PP(name) + 1, (void *) &d) == SUCCESS) { php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name)); php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC); } else { @@ -666,7 +678,7 @@ static void php_var_serialize_class(smart_str *buf, zv do { zend_mangle_property_name(&priv_name, &prop_name_length, ce->name, ce->name_length, Z_STRVAL_PP(name), Z_STRLEN_PP(name), ce->type & ZEND_INTERNAL_CLASS); - if (zend_hash_find(Z_OBJPROP_P(struc), priv_name, prop_name_length + 1, (void *) &d) == SUCCESS) { + if (zend_hash_find(propers, priv_name, prop_name_length + 1, (void *) &d) == SUCCESS) { php_var_serialize_string(buf, priv_name, prop_name_length); pefree(priv_name, ce->type & ZEND_INTERNAL_CLASS); php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC); @@ -674,7 +686,7 @@ static void php_var_serialize_class(smart_str *buf, zv } pefree(priv_name, ce->type & ZEND_INTERNAL_CLASS); zend_mangle_property_name(&prot_name, &prop_name_length, "*", 1, Z_STRVAL_PP(name), Z_STRLEN_PP(name), ce->type & ZEND_INTERNAL_CLASS); - if (zend_hash_find(Z_OBJPROP_P(struc), prot_name, prop_name_length + 1, (void *) &d) == SUCCESS) { + if (zend_hash_find(propers, prot_name, prop_name_length + 1, (void *) &d) == SUCCESS) { php_var_serialize_string(buf, prot_name, prop_name_length); pefree(prot_name, ce->type & ZEND_INTERNAL_CLASS); php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC); @@ -702,6 +714,10 @@ static void php_var_serialize_intern(smart_str *buf, z ulong *var_already; HashTable *myht; + if (EG(exception)) { + return; + } + if (var_hash && php_add_var_hash(var_hash, struc, (void *) &var_already TSRMLS_CC) == FAILURE) { if (Z_ISREF_P(struc)) { smart_str_appendl(buf, "R:", 2); @@ -785,9 +801,18 @@ static void php_var_serialize_intern(smart_str *buf, z if (ce && ce != PHP_IC_ENTRY && zend_hash_exists(&ce->function_table, "__sleep", sizeof("__sleep"))) { INIT_PZVAL(&fname); ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1, 0); + BG(serialize_lock)++; res = call_user_function_ex(CG(function_table), &struc, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC); + BG(serialize_lock)--; + + if (EG(exception)) { + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + return; + } - if (res == SUCCESS && !EG(exception)) { + if (res == SUCCESS) { if (retval_ptr) { if (HASH_OF(retval_ptr)) { php_var_serialize_class(buf, struc, retval_ptr, var_hash TSRMLS_CC); @@ -880,9 +905,9 @@ static void php_var_serialize_intern(smart_str *buf, z } /* }}} */ -PHPAPI void php_var_serialize(smart_str *buf, zval **struc, HashTable *var_hash TSRMLS_DC) /* {{{ */ +PHPAPI void php_var_serialize(smart_str *buf, zval **struc, php_serialize_data_t *var_hash TSRMLS_DC) /* {{{ */ { - php_var_serialize_intern(buf, *struc, var_hash TSRMLS_CC); + php_var_serialize_intern(buf, *struc, *var_hash TSRMLS_CC); smart_str_0(buf); } /* }}} */ @@ -907,6 +932,11 @@ PHP_FUNCTION(serialize) php_var_serialize(&buf, struc, &var_hash TSRMLS_CC); PHP_VAR_SERIALIZE_DESTROY(var_hash); + if (EG(exception)) { + smart_str_free(&buf); + RETURN_FALSE; + } + if (buf.c) { RETURN_STRINGL(buf.c, buf.len, 0); } else { @@ -937,7 +967,9 @@ PHP_FUNCTION(unserialize) if (!php_var_unserialize(&return_value, &p, p + buf_len, &var_hash TSRMLS_CC)) { PHP_VAR_UNSERIALIZE_DESTROY(var_hash); zval_dtor(return_value); - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len); + if (!EG(exception)) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len); + } RETURN_FALSE; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash);