]> granicus.if.org Git - php/commitdiff
Fixed bug #79951
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 11 Aug 2020 08:33:59 +0000 (10:33 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 11 Aug 2020 08:33:59 +0000 (10:33 +0200)
One branch did not release tmp_replace_entry_str.

Also reduce the scope of some variables.

NEWS
ext/standard/string.c
ext/standard/tests/strings/bug79951.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 410b74a89358735f2470daaf91d7914ddcf0b247..782447d9926c03e98c04e00828a837bd723a9808 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,7 @@ PHP                                                                        NEWS
   . Fixed bug #79930 (array_merge_recursive() crashes when called with array
     with single reference). (Nikita)
   . Fixed bug #79944 (getmxrr always returns true on Alpine linux). (Nikita)
+  . Fixed bug #79951 (Memory leak in str_replace of empty string). (Nikita)
 
 - XML:
   . Fixed bug #79922 (Crash after multiple calls to xml_parser_free()). (cmb)
index 8cf206533ab06b8b57951d6774919d6b6a535997..b070a5e827fd5cfd2e0bdb98a18cae4ee1f8d721 100644 (file)
@@ -4269,12 +4269,9 @@ PHPAPI void php_stripslashes(zend_string *str)
  */
 static zend_long php_str_replace_in_subject(zval *search, zval *replace, zval *subject, zval *result, int case_sensitivity)
 {
-       zval            *search_entry,
-                               *replace_entry = NULL;
+       zval            *search_entry;
        zend_string     *tmp_result,
-                   *tmp_subject_str,
-                   *tmp_replace_entry_str = NULL,
-                               *replace_entry_str;
+                   *tmp_subject_str;
        char            *replace_value = NULL;
        size_t           replace_len = 0;
        zend_long        replace_count = 0;
@@ -4308,10 +4305,12 @@ static zend_long php_str_replace_in_subject(zval *search, zval *replace, zval *s
                        /* Make sure we're dealing with strings. */
                        zend_string *tmp_search_str;
                        zend_string *search_str = zval_get_tmp_string(search_entry, &tmp_search_str);
+                       zend_string *replace_entry_str, *tmp_replace_entry_str = NULL;
 
                        /* If replace is an array. */
                        if (Z_TYPE_P(replace) == IS_ARRAY) {
                                /* Get current entry */
+                               zval *replace_entry = NULL;
                                while (replace_idx < Z_ARRVAL_P(replace)->nNumUsed) {
                                        replace_entry = &Z_ARRVAL_P(replace)->arData[replace_idx].val;
                                        if (Z_TYPE_P(replace_entry) != IS_UNDEF) {
@@ -4368,15 +4367,12 @@ static zend_long php_str_replace_in_subject(zval *search, zval *replace, zval *s
                                }
                        } else {
                                zend_tmp_string_release(tmp_search_str);
+                               zend_tmp_string_release(tmp_replace_entry_str);
                                continue;
                        }
 
                        zend_tmp_string_release(tmp_search_str);
-
-                       if (tmp_replace_entry_str) {
-                               zend_string_release_ex(tmp_replace_entry_str, 0);
-                               tmp_replace_entry_str = NULL;
-                       }
+                       zend_tmp_string_release(tmp_replace_entry_str);
 
                        if (subject_str == tmp_result) {
                                zend_string_delref(subject_str);
diff --git a/ext/standard/tests/strings/bug79951.phpt b/ext/standard/tests/strings/bug79951.phpt
new file mode 100644 (file)
index 0000000..5663ba6
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+Bug #79951: Memory leak in str_replace of empty string
+--FILE--
+<?php
+
+var_dump(str_replace([""], [1000], "foo"));
+
+?>
+--EXPECT--
+string(3) "foo"