]> granicus.if.org Git - php/commitdiff
Properly fix #80220
authorChristoph M. Becker <cmbecker69@gmx.de>
Fri, 16 Oct 2020 09:58:50 +0000 (11:58 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Tue, 20 Oct 2020 11:32:53 +0000 (13:32 +0200)
The original fix for that bug[1] broke the formerly working composition
of message/rfc822 messages, which results in a segfault when freeing
the message body now.  While `imap_mail_compose()` does not really
support composition of meaningful message/rfc822 messages (although
libc-client appears to support that), some code may still use this to
compose partial messages, and using string manipulation to create the
final message.

The point is that libc-client expects `TYPEMESSAGE` with an explicit
subtype of `RFC822` to have a `nested.msg` (otherwise there will be a
segfault during free), but not to have any `contents.text.data` (this
will leak otherwise).

[1] <http://git.php.net/?p=php-src.git;a=commit;h=0d022ddf03c5fabaaa22e486d1e4a367ed9170a7>

Closes GH-6343.

NEWS
ext/imap/php_imap.c
ext/imap/tests/bug80220.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 42b663cf409a2716599a99b1733b13ee4eefc433..05d3b73b86945c8aa76df29a8f2760985b52dfd2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ PHP                                                                        NEWS
 - IMAP:
   . Fixed bug #64076 (imap_sort() does not return FALSE on failure). (cmb)
   . Fixed bug #80239 (imap_rfc822_write_address() leaks memory). (cmb)
+  . Fixed minor regression caused by fixing bug #80220. (cmb)
 
 29 Oct 2020, PHP 7.3.24
 
index d3b3986ad5a0fd29284cd95b9cd2f05a9bc8a855..084cb4ee28656396c8907f9a74d8fbae2c7fae00 100644 (file)
@@ -3706,15 +3706,19 @@ PHP_FUNCTION(imap_mail_compose)
                                        bod->disposition.parameter = disp_param;
                                }
                        }
-                       if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "contents.data", sizeof("contents.data") - 1)) != NULL) {
-                               convert_to_string_ex(pvalue);
-                               bod->contents.text.data = fs_get(Z_STRLEN_P(pvalue) + 1);
-                               memcpy(bod->contents.text.data, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue)+1);
-                               bod->contents.text.size = Z_STRLEN_P(pvalue);
+                       if (bod->type == TYPEMESSAGE && bod->subtype && !strcmp(bod->subtype, "RFC822")) {
+                               bod->nested.msg = mail_newmsg();
                        } else {
-                               bod->contents.text.data = fs_get(1);
-                               memcpy(bod->contents.text.data, "", 1);
-                               bod->contents.text.size = 0;
+                               if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "contents.data", sizeof("contents.data") - 1)) != NULL) {
+                                       convert_to_string_ex(pvalue);
+                                       bod->contents.text.data = fs_get(Z_STRLEN_P(pvalue) + 1);
+                                       memcpy(bod->contents.text.data, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue)+1);
+                                       bod->contents.text.size = Z_STRLEN_P(pvalue);
+                               } else {
+                                       bod->contents.text.data = fs_get(1);
+                                       memcpy(bod->contents.text.data, "", 1);
+                                       bod->contents.text.size = 0;
+                               }
                        }
                        if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "lines", sizeof("lines") - 1)) != NULL) {
                                bod->size.lines = zval_get_long(pvalue);
@@ -3933,7 +3937,7 @@ PHP_FUNCTION(imap_mail_compose)
                        efree(mystring);
                        mystring=tempstring;
        } else if (bod) {
-               spprintf(&tempstring, 0, "%s%s%s", mystring, bod->contents.text.data, CRLF);
+               spprintf(&tempstring, 0, "%s%s%s", mystring, bod->contents.text.data ? bod->contents.text.data : "", CRLF);
                efree(mystring);
                mystring=tempstring;
        } else {
diff --git a/ext/imap/tests/bug80220.phpt b/ext/imap/tests/bug80220.phpt
new file mode 100644 (file)
index 0000000..0d3e3ed
--- /dev/null
@@ -0,0 +1,34 @@
+--TEST--
+Bug #80220 (imap_mail_compose() may leak memory) - message/rfc822 regression
+--SKIPIF--
+<?php
+if (!extension_loaded('imap')) die('skip imap extension not available');
+?>
+--FILE--
+<?php
+$bodies = [[
+    'type' => TYPEMESSAGE,
+    'subtype' => 'RFC822',
+], [
+    'contents.data' => 'asd',
+]];
+var_dump(imap_mail_compose([], $bodies));
+
+$bodies = [[
+    'type' => TYPEMESSAGE,
+], [
+    'contents.data' => 'asd',
+]];
+var_dump(imap_mail_compose([], $bodies));
+?>
+--EXPECT--
+string(53) "MIME-Version: 1.0
+Content-Type: MESSAGE/RFC822
+
+
+"
+string(53) "MIME-Version: 1.0
+Content-Type: MESSAGE/RFC822
+
+
+"