Skip to content

Commit 1e1b72f

Browse files
committed
Reduce memory allocated by var_export, json_encode, serialize, and other
1 parent 9a7d37a commit 1e1b72f

File tree

14 files changed

+46
-43
lines changed

14 files changed

+46
-43
lines changed

Zend/zend_smart_str.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
smart_str_appendl_ex((dest), (src), strlen(src), (what))
2626
#define smart_str_appends(dest, src) \
2727
smart_str_appendl((dest), (src), strlen(src))
28+
#define smart_str_finalize(dest) \
29+
smart_str_finalize_ex((dest), 0)
2830
#define smart_str_extend(dest, len) \
2931
smart_str_extend_ex((dest), (len), 0)
3032
#define smart_str_appendc(dest, c) \
@@ -76,6 +78,29 @@ static zend_always_inline size_t smart_str_alloc(smart_str *str, size_t len, boo
7678
return len;
7779
}
7880

81+
static zend_always_inline void smart_str_trim_to_len(smart_str *str, bool persistent)
82+
{
83+
if (str->s && str->a > ZSTR_LEN(str->s)) {
84+
str->s = zend_string_realloc(str->s, ZSTR_LEN(str->s), persistent);
85+
str->a = ZSTR_LEN(str->s);
86+
}
87+
}
88+
89+
static zend_always_inline zend_string* smart_str_finalize_ex(smart_str *str, bool persistent)
90+
{
91+
if (UNEXPECTED(!str->s)) {
92+
return ZSTR_EMPTY_ALLOC();
93+
}
94+
95+
smart_str_trim_to_len(str, persistent);
96+
zend_string *retval = str->s;
97+
98+
str->s = NULL;
99+
str->a = 0;
100+
101+
return retval;
102+
}
103+
79104
static zend_always_inline char* smart_str_extend_ex(smart_str *dest, size_t len, bool persistent) {
80105
size_t new_len = smart_str_alloc(dest, len, persistent);
81106
char *ret = ZSTR_VAL(dest->s) + ZSTR_LEN(dest->s);

ext/dom/documenttype.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ int dom_documenttype_internal_subset_read(dom_object *obj, zval *retval)
189189

190190
if (ret_buf.s) {
191191
smart_str_0(&ret_buf);
192-
ZVAL_NEW_STR(retval, ret_buf.s);
192+
ZVAL_STR(retval, smart_str_finalize(&ret_buf));
193193
return SUCCESS;
194194
}
195195
}

ext/filter/sanitizing_filters.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static void php_filter_encode_html(zval *value, const unsigned char *chars)
4848

4949
smart_str_0(&str);
5050
zval_ptr_dtor(value);
51-
ZVAL_NEW_STR(value, str.s);
51+
ZVAL_STR(value, smart_str_finalize(&str));
5252
}
5353

5454
static const unsigned char hexchars[] = "0123456789ABCDEF";

ext/iconv/iconv.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,7 +1845,7 @@ PHP_FUNCTION(iconv_substr)
18451845
_php_iconv_show_error(err, GENERIC_SUPERSET_NAME, charset);
18461846

18471847
if (err == PHP_ICONV_ERR_SUCCESS && retval.s != NULL) {
1848-
RETURN_NEW_STR(retval.s);
1848+
RETURN_STR(smart_str_finalize(&retval));
18491849
}
18501850
smart_str_free(&retval);
18511851
RETURN_FALSE;
@@ -2038,11 +2038,7 @@ PHP_FUNCTION(iconv_mime_encode)
20382038
_php_iconv_show_error(err, out_charset, in_charset);
20392039

20402040
if (err == PHP_ICONV_ERR_SUCCESS) {
2041-
if (retval.s != NULL) {
2042-
RETVAL_STR(retval.s);
2043-
} else {
2044-
RETVAL_EMPTY_STRING();
2045-
}
2041+
RETVAL_STR(smart_str_finalize(&retval));
20462042
} else {
20472043
smart_str_free(&retval);
20482044
RETVAL_FALSE;
@@ -2083,11 +2079,7 @@ PHP_FUNCTION(iconv_mime_decode)
20832079
_php_iconv_show_error(err, charset, "???");
20842080

20852081
if (err == PHP_ICONV_ERR_SUCCESS) {
2086-
if (retval.s != NULL) {
2087-
RETVAL_STR(retval.s);
2088-
} else {
2089-
RETVAL_EMPTY_STRING();
2090-
}
2082+
RETVAL_STR(smart_str_finalize(&retval));
20912083
} else {
20922084
smart_str_free(&retval);
20932085
RETVAL_FALSE;

ext/json/json.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,8 @@ PHP_FUNCTION(json_encode)
212212
}
213213
}
214214

215-
smart_str_0(&buf); /* copy? */
216-
if (buf.s) {
217-
RETURN_NEW_STR(buf.s);
218-
}
219-
RETURN_EMPTY_STRING();
215+
smart_str_0(&buf);
216+
RETURN_STR(smart_str_finalize(&buf));
220217
}
221218
/* }}} */
222219

ext/mbstring/php_mbregex.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,12 +1145,10 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
11451145
if (err <= -2) {
11461146
smart_str_free(&out_buf);
11471147
RETVAL_FALSE;
1148-
} else if (out_buf.s) {
1149-
smart_str_0(&out_buf);
1150-
RETVAL_STR(out_buf.s);
1151-
} else {
1152-
RETVAL_EMPTY_STRING();
11531148
}
1149+
1150+
smart_str_0(&out_buf);
1151+
RETVAL_STR(smart_str_finalize(&out_buf));
11541152
}
11551153
/* }}} */
11561154

ext/session/session.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,7 @@ PHPAPI zend_result php_session_reset_id(void) /* {{{ */
14641464
smart_str_0(&var);
14651465
if (sid) {
14661466
zval_ptr_dtor_str(sid);
1467-
ZVAL_NEW_STR(sid, var.s);
1467+
ZVAL_STR(sid, smart_str_finalize(&var));
14681468
} else {
14691469
REGISTER_STRINGL_CONSTANT("SID", ZSTR_VAL(var.s), ZSTR_LEN(var.s), 0);
14701470
smart_str_free(&var);
@@ -2363,7 +2363,7 @@ PHP_FUNCTION(session_create_id)
23632363
RETURN_FALSE;
23642364
}
23652365
smart_str_0(&id);
2366-
RETVAL_NEW_STR(id.s);
2366+
RETVAL_STR(smart_str_finalize(&id));
23672367
}
23682368
/* }}} */
23692369

ext/soap/php_sdl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3262,7 +3262,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl)
32623262
smart_str_appends(&proxy,":");
32633263
smart_str_append_long(&proxy,Z_LVAL_P(proxy_port));
32643264
smart_str_0(&proxy);
3265-
ZVAL_NEW_STR(&str_proxy, proxy.s);
3265+
ZVAL_STR(&str_proxy, smart_str_finalize(&proxy));
32663266

32673267
if (!context) {
32683268
context = php_stream_context_alloc();
@@ -3305,7 +3305,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl)
33053305
}
33063306

33073307
smart_str_0(&headers);
3308-
ZVAL_NEW_STR(&str_headers, headers.s);
3308+
ZVAL_STR(&str_headers, smart_str_finalize(&headers));
33093309
php_stream_context_set_option(context, "http", "header", &str_headers);
33103310
zval_ptr_dtor(&str_headers);
33113311
}

ext/spl/spl_array.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1554,7 +1554,7 @@ PHP_METHOD(ArrayObject, serialize)
15541554
/* done */
15551555
PHP_VAR_SERIALIZE_DESTROY(var_hash);
15561556

1557-
RETURN_NEW_STR(buf.s);
1557+
RETURN_STR(smart_str_finalize(&buf));
15581558
} /* }}} */
15591559

15601560
/* {{{ unserialize the object */

ext/spl/spl_dllist.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ PHP_METHOD(SplDoublyLinkedList, serialize)
10371037
/* done */
10381038
PHP_VAR_SERIALIZE_DESTROY(var_hash);
10391039

1040-
RETURN_NEW_STR(buf.s);
1040+
RETURN_STR(smart_str_finalize(&buf));
10411041
} /* }}} */
10421042

10431043
/* {{{ Unserializes storage */

ext/spl/spl_observer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ PHP_METHOD(SplObjectStorage, serialize)
808808
/* done */
809809
PHP_VAR_SERIALIZE_DESTROY(var_hash);
810810

811-
RETURN_NEW_STR(buf.s);
811+
RETURN_STR(smart_str_finalize(&buf));
812812
} /* }}} */
813813

814814
/* {{{ Unserializes storage */

ext/standard/http.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,12 +238,7 @@ PHP_FUNCTION(http_build_query)
238238

239239
php_url_encode_hash_ex(HASH_OF(formdata), &formstr, prefix, prefix_len, NULL, 0, NULL, 0, (Z_TYPE_P(formdata) == IS_OBJECT ? formdata : NULL), arg_sep, (int)enc_type);
240240

241-
if (!formstr.s) {
242-
RETURN_EMPTY_STRING();
243-
}
244-
245241
smart_str_0(&formstr);
246-
247-
RETURN_NEW_STR(formstr.s);
242+
RETURN_STR(smart_str_finalize(&formstr));
248243
}
249244
/* }}} */

ext/standard/string.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2892,7 +2892,7 @@ static void php_strtr_array(zval *return_value, zend_string *input, HashTable *p
28922892
if (result.s) {
28932893
smart_str_appendl(&result, str + old_pos, slen - old_pos);
28942894
smart_str_0(&result);
2895-
RETVAL_NEW_STR(result.s);
2895+
RETVAL_STR(smart_str_finalize(&result));
28962896
} else {
28972897
smart_str_free(&result);
28982898
RETVAL_STR_COPY(input);

ext/standard/var.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ PHP_FUNCTION(var_export)
645645
smart_str_0 (&buf);
646646

647647
if (return_output) {
648-
RETURN_NEW_STR(buf.s);
648+
RETURN_STR(smart_str_finalize(&buf));
649649
} else {
650650
PHPWRITE(ZSTR_VAL(buf.s), ZSTR_LEN(buf.s));
651651
smart_str_free(&buf);
@@ -1318,11 +1318,7 @@ PHP_FUNCTION(serialize)
13181318
RETURN_THROWS();
13191319
}
13201320

1321-
if (buf.s) {
1322-
RETURN_NEW_STR(buf.s);
1323-
} else {
1324-
RETURN_EMPTY_STRING();
1325-
}
1321+
RETURN_STR(smart_str_finalize(&buf));
13261322
}
13271323
/* }}} */
13281324

0 commit comments

Comments
 (0)