pajoye Tue, 13 Jul 2010 18:53:12 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=301245
Log: - MFH: Fix a bug when var_export() causes a fatal error that could inadvertently display data due to flushing of the output buffer. Changed paths: U php/php-src/branches/PHP_5_2/ext/standard/php_var.h U php/php-src/branches/PHP_5_2/ext/standard/tests/general_functions/var_export_error2.phpt U php/php-src/branches/PHP_5_2/ext/standard/tests/general_functions/var_export_error3.phpt U php/php-src/branches/PHP_5_2/ext/standard/var.c
Modified: php/php-src/branches/PHP_5_2/ext/standard/php_var.h =================================================================== --- php/php-src/branches/PHP_5_2/ext/standard/php_var.h 2010-07-13 17:24:44 UTC (rev 301244) +++ php/php-src/branches/PHP_5_2/ext/standard/php_var.h 2010-07-13 18:53:12 UTC (rev 301245) @@ -33,6 +33,8 @@ PHPAPI void php_var_dump(zval **struc, int level TSRMLS_DC); PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC); +PHPAPI void php_var_export_ex(zval **struc, int level, smart_str *buf TSRMLS_DC); + PHPAPI void php_debug_zval_dump(zval **struc, int level TSRMLS_DC); /* typdef HashTable php_serialize_data_t; */ Modified: php/php-src/branches/PHP_5_2/ext/standard/tests/general_functions/var_export_error2.phpt =================================================================== --- php/php-src/branches/PHP_5_2/ext/standard/tests/general_functions/var_export_error2.phpt 2010-07-13 17:24:44 UTC (rev 301244) +++ php/php-src/branches/PHP_5_2/ext/standard/tests/general_functions/var_export_error2.phpt 2010-07-13 18:53:12 UTC (rev 301245) @@ -14,12 +14,5 @@ ?> ===DONE=== --EXPECTF-- -stdClass::__set_state(array( - 'p' => - stdClass::__set_state(array( - 'p' => - stdClass::__set_state(array( - 'p' => - stdClass::__set_state(array( Fatal error: Nesting level too deep - recursive dependency? in %s on line 9 \ No newline at end of file Modified: php/php-src/branches/PHP_5_2/ext/standard/tests/general_functions/var_export_error3.phpt =================================================================== --- php/php-src/branches/PHP_5_2/ext/standard/tests/general_functions/var_export_error3.phpt 2010-07-13 17:24:44 UTC (rev 301244) +++ php/php-src/branches/PHP_5_2/ext/standard/tests/general_functions/var_export_error3.phpt 2010-07-13 18:53:12 UTC (rev 301245) @@ -14,14 +14,5 @@ ?> ===DONE=== --EXPECTF-- -array ( - 0 => - array ( - 0 => - array ( - 0 => - array ( - 0 => - array ( Fatal error: Nesting level too deep - recursive dependency? in %s on line 9 \ No newline at end of file Modified: php/php-src/branches/PHP_5_2/ext/standard/var.c =================================================================== --- php/php-src/branches/PHP_5_2/ext/standard/var.c 2010-07-13 17:24:44 UTC (rev 301244) +++ php/php-src/branches/PHP_5_2/ext/standard/var.c 2010-07-13 18:53:12 UTC (rev 301245) @@ -346,54 +346,83 @@ } /* }}} */ +#define buffer_append_spaces(buf, num_spaces) \ + do { \ + char *tmp_spaces; \ + int tmp_spaces_len; \ + tmp_spaces_len = spprintf(&tmp_spaces, 0,"%*c", num_spaces, ' '); \ + smart_str_appendl(buf, tmp_spaces, tmp_spaces_len); \ + efree(tmp_spaces); \ + } while(0); /* {{{ php_var_export */ static int php_array_element_export(zval **zv, int num_args, va_list args, zend_hash_key *hash_key) { int level; + smart_str *buf; + TSRMLS_FETCH(); level = va_arg(args, int); + buf = va_arg(args, smart_str *); - if (hash_key->nKeyLength==0) { /* numeric key */ - php_printf("%*c%ld => ", level + 1, ' ', hash_key->h); + if (hash_key->nKeyLength == 0) { /* numeric key */ + buffer_append_spaces(buf, level+1); + smart_str_append_long(buf, hash_key->h); + smart_str_appendl(buf, " => ", 4); } else { /* string key */ char *key, *tmp_str; int key_len, tmp_len; key = php_addcslashes(hash_key->arKey, hash_key->nKeyLength - 1, &key_len, 0, "'\\", 2 TSRMLS_CC); tmp_str = php_str_to_str_ex(key, key_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len, 0, NULL); - php_printf("%*c'", level + 1, ' '); - PHPWRITE(tmp_str, tmp_len); - php_printf("' => "); + + buffer_append_spaces(buf, level + 1); + + smart_str_appendc(buf, '\''); + smart_str_appendl(buf, tmp_str, tmp_len); + smart_str_appendl(buf, "' => ", 5); + efree(key); efree(tmp_str); } - php_var_export(zv, level + 2 TSRMLS_CC); - PUTS (",\n"); + php_var_export_ex(zv, level + 2, buf TSRMLS_CC); + + smart_str_appendc(buf, ','); + smart_str_appendc(buf, '\n'); + return 0; } static int php_object_element_export(zval **zv, int num_args, va_list args, zend_hash_key *hash_key) { int level; + smart_str *buf; char *prop_name, *class_name; TSRMLS_FETCH(); level = va_arg(args, int); + buf = va_arg(args, smart_str *); - php_printf("%*c", level + 1, ' '); + buffer_append_spaces(buf, level + 2); if (hash_key->nKeyLength != 0) { zend_unmangle_property_name(hash_key->arKey, hash_key->nKeyLength - 1, &class_name, &prop_name); - php_printf(" '%s' => ", prop_name); + + smart_str_appendc(buf, '\''); + smart_str_appends(buf, prop_name); + smart_str_appendc(buf, '\''); } else { - php_printf(" %ld => ", hash_key->h); + smart_str_append_long(buf, hash_key->h); } - php_var_export(zv, level + 2 TSRMLS_CC); - PUTS (",\n"); + + 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; } -PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC) +PHPAPI void php_var_export_ex(zval **struc, int level, smart_str *buf TSRMLS_DC) /* {{{ */ { HashTable *myht; char *tmp_str, *tmp_str2; @@ -403,60 +432,85 @@ switch (Z_TYPE_PP(struc)) { case IS_BOOL: - php_printf("%s", Z_LVAL_PP(struc) ? "true" : "false"); + if (Z_LVAL_PP(struc)) { + smart_str_appendl(buf, "true", 4); + } else { + smart_str_appendl(buf, "false", 5); + } break; case IS_NULL: - php_printf("NULL"); + smart_str_appendl(buf, "NULL", 4); break; case IS_LONG: - php_printf("%ld", Z_LVAL_PP(struc)); + smart_str_append_long(buf, Z_LVAL_PP(struc)); break; case IS_DOUBLE: - php_printf("%.*H", (int) EG(precision), Z_DVAL_PP(struc)); + tmp_len = spprintf(&tmp_str, 0,"%.*H", (int) EG(precision), Z_DVAL_PP(struc)); + smart_str_appendl(buf, tmp_str, tmp_len); + efree(tmp_str); break; case IS_STRING: tmp_str = php_addcslashes(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc), &tmp_len, 0, "'\\", 2 TSRMLS_CC); tmp_str2 = php_str_to_str_ex(tmp_str, tmp_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len2, 0, NULL); - PUTS ("'"); - PHPWRITE(tmp_str2, tmp_len2); - PUTS ("'"); + + smart_str_appendc(buf, '\''); + smart_str_appendl(buf, tmp_str2, tmp_len2); + smart_str_appendc(buf, '\''); + efree(tmp_str2); efree(tmp_str); break; case IS_ARRAY: myht = Z_ARRVAL_PP(struc); if (level > 1) { - php_printf("\n%*c", level - 1, ' '); + smart_str_appendc(buf, '\n'); + buffer_append_spaces(buf, level - 1); } - PUTS ("array (\n"); - zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_array_element_export, 1, level, 0); + smart_str_appendl(buf, "array (\n", 8); + zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_array_element_export, 2, level, buf); + if (level > 1) { - php_printf("%*c", level - 1, ' '); + buffer_append_spaces(buf, level - 1); } - PUTS(")"); + smart_str_appendc(buf, ')'); + break; case IS_OBJECT: myht = Z_OBJPROP_PP(struc); if (level > 1) { - php_printf("\n%*c", level - 1, ' '); + smart_str_appendc(buf, '\n'); + buffer_append_spaces(buf, level - 1); } Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC); - php_printf ("%s::__set_state(array(\n", class_name); + + smart_str_appendl(buf, class_name, class_name_len); + smart_str_appendl(buf, "::__set_state(array(\n", 21); + efree(class_name); if (myht) { - zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_object_element_export, 1, level); + zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_object_element_export, 2, level, buf); } if (level > 1) { - php_printf("%*c", level - 1, ' '); + buffer_append_spaces(buf, level - 1); } - php_printf ("))"); + smart_str_appendl(buf, "))", 2); + break; default: - PUTS ("NULL"); + smart_str_appendl(buf, "NULL", 4); break; } } +/* FOR BC reasons, this will always perform and then print */ +PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC) /* {{{ */ +{ + smart_str buf = {0}; + php_var_export_ex(struc, level, &buf TSRMLS_CC); + smart_str_0 (&buf); + PHPWRITE(buf.c, buf.len); + smart_str_free(&buf); +} /* }}} */ /* {{{ proto mixed var_export(mixed var [, bool return]) @@ -465,21 +519,21 @@ { zval *var; zend_bool return_output = 0; - + smart_str buf = {0}; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &return_output) == FAILURE) { return; } - - if (return_output) { - php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); - } - - php_var_export(&var, 1 TSRMLS_CC); + php_var_export_ex(&var, 1, &buf TSRMLS_CC); + smart_str_0 (&buf); + if (return_output) { - php_ob_get_buffer (return_value TSRMLS_CC); - php_end_ob_buffer (0, 0 TSRMLS_CC); + RETVAL_STRINGL(buf.c, buf.len, 1); + } else { + PHPWRITE(buf.c, buf.len); } + smart_str_free(&buf); } /* }}} */
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php