Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@ PHP 8.6 UPGRADE NOTES
. Improved performance of array_walk().
. Improved performance of intval('+0b...', 2) and intval('0b...', 2).
. Improved performance of str_split().
. Improved performance of var_export().

- URI:
. Improved performance of Uri\WhatWg\Url::parse() when collecting
Expand Down
82 changes: 47 additions & 35 deletions ext/standard/var.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,14 +467,49 @@ PHP_FUNCTION(debug_zval_dump)
}
/* }}} */

#define buffer_append_spaces(buf, num_spaces) \
do { \
char *tmp_spaces; \
size_t 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);
static void buffer_append_spaces(smart_str *buf, int num_spaces)
{
char *target = smart_str_extend(buf, (size_t) num_spaces);
memset(target, ' ', num_spaces);
}

static size_t php_var_export_compute_escaped_string_len(const char *str, size_t len, bool escape_nul)
{
size_t i, escaped_len = len;
for (i = 0; i < len; ++i) {
char c = str[i];
if (c == '\'' || c == '\\') {
escaped_len += 1;
} else if (escape_nul && c == '\0') {
escaped_len += 11;
}
}
return escaped_len;
}

static void php_var_export_append_escaped(smart_str *buf, const char *str, size_t len, bool escape_nul)
{
size_t escaped_len = php_var_export_compute_escaped_string_len(str, len, escape_nul);

smart_str_appendc(buf, '\'');
if (escaped_len == len) {
smart_str_appendl(buf, str, len);
} else {
char *target = smart_str_extend(buf, escaped_len);
for (size_t i = 0; i < len; i++) {
char c = str[i];
if (c == '\'' || c == '\\') {
*target++ = '\\';
*target++ = c;
} else if (escape_nul && c == '\0') {
target = zend_mempcpy(target, "' . \"\\0\" . '", 12);
} else {
*target++ = c;
}
}
}
smart_str_appendc(buf, '\'');
}

static zend_result php_array_element_export(zval *zv, zend_ulong index, zend_string *key, int level, smart_str *buf) /* {{{ */
{
Expand All @@ -484,18 +519,10 @@ static zend_result php_array_element_export(zval *zv, zend_ulong index, zend_str
smart_str_appendl(buf, " => ", 4);

} else { /* string key */
zend_string *tmp_str;
zend_string *ckey = php_addcslashes(key, "'\\", 2);
tmp_str = php_str_to_str(ZSTR_VAL(ckey), ZSTR_LEN(ckey), "\0", 1, "' . \"\\0\" . '", 12);

buffer_append_spaces(buf, level + 1);

smart_str_appendc(buf, '\'');
smart_str_append(buf, tmp_str);
smart_str_appendl(buf, "' => ", 5);

zend_string_free(ckey);
zend_string_free(tmp_str);
php_var_export_append_escaped(buf, ZSTR_VAL(key), ZSTR_LEN(key), /* escape_nul */ true);
smart_str_appendl(buf, " => ", 4);
}
zend_result result = php_var_export_ex(zv, level + 2, buf);

Expand All @@ -512,15 +539,9 @@ static zend_result php_object_element_export(zval *zv, zend_ulong index, zend_st
if (key != NULL) {
const char *class_name, *prop_name;
size_t prop_name_len;
zend_string *pname_esc;

zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_name_len);
pname_esc = php_addcslashes_str(prop_name, prop_name_len, "'\\", 2);

smart_str_appendc(buf, '\'');
smart_str_append(buf, pname_esc);
smart_str_appendc(buf, '\'');
zend_string_release_ex(pname_esc, 0);
php_var_export_append_escaped(buf, prop_name, prop_name_len, /* escape_nul */ false);
} else {
smart_str_append_long(buf, (zend_long) index);
}
Expand All @@ -536,7 +557,6 @@ static zend_result php_object_element_export(zval *zv, zend_ulong index, zend_st
PHPAPI zend_result php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */
{
HashTable *myht;
zend_string *ztmp, *ztmp2;
zend_ulong index;
zend_string *key;
zval *val;
Expand Down Expand Up @@ -567,15 +587,7 @@ PHPAPI zend_result php_var_export_ex(zval *struc, int level, smart_str *buf) /*
buf, Z_DVAL_P(struc), (int) PG(serialize_precision), /* zero_fraction */ true);
break;
case IS_STRING:
ztmp = php_addcslashes(Z_STR_P(struc), "'\\", 2);
ztmp2 = php_str_to_str(ZSTR_VAL(ztmp), ZSTR_LEN(ztmp), "\0", 1, "' . \"\\0\" . '", 12);

smart_str_appendc(buf, '\'');
smart_str_append(buf, ztmp2);
smart_str_appendc(buf, '\'');

zend_string_free(ztmp);
zend_string_free(ztmp2);
php_var_export_append_escaped(buf, Z_STRVAL_P(struc), Z_STRLEN_P(struc), /* escape_nul */ true);
break;
case IS_ARRAY:
myht = Z_ARRVAL_P(struc);
Expand Down
Loading