Skip to content

Commit 315b95b

Browse files
committed
Fix #80242: imap_mail_compose() segfaults for multipart with rfc822
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). Closes GH-6345.
1 parent de58fb3 commit 315b95b

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ PHP NEWS
66
. Fixed bug #64076 (imap_sort() does not return FALSE on failure). (cmb)
77
. Fixed bug #80239 (imap_rfc822_write_address() leaks memory). (cmb)
88
. Fixed minor regression caused by fixing bug #80220. (cmb)
9+
. Fixed bug #80242 (imap_mail_compose() segfaults for multipart with rfc822).
10+
(cmb)
911

1012
29 Oct 2020, PHP 7.3.24
1113

ext/imap/php_imap.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3818,15 +3818,19 @@ PHP_FUNCTION(imap_mail_compose)
38183818
bod->disposition.parameter = disp_param;
38193819
}
38203820
}
3821-
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "contents.data", sizeof("contents.data") - 1)) != NULL) {
3822-
convert_to_string_ex(pvalue);
3823-
bod->contents.text.data = fs_get(Z_STRLEN_P(pvalue) + 1);
3824-
memcpy(bod->contents.text.data, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue) + 1);
3825-
bod->contents.text.size = Z_STRLEN_P(pvalue);
3821+
if (bod->type == TYPEMESSAGE && bod->subtype && !strcmp(bod->subtype, "RFC822")) {
3822+
bod->nested.msg = mail_newmsg();
38263823
} else {
3827-
bod->contents.text.data = fs_get(1);
3828-
memcpy(bod->contents.text.data, "", 1);
3829-
bod->contents.text.size = 0;
3824+
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "contents.data", sizeof("contents.data") - 1)) != NULL) {
3825+
convert_to_string_ex(pvalue);
3826+
bod->contents.text.data = fs_get(Z_STRLEN_P(pvalue) + 1);
3827+
memcpy(bod->contents.text.data, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue) + 1);
3828+
bod->contents.text.size = Z_STRLEN_P(pvalue);
3829+
} else {
3830+
bod->contents.text.data = fs_get(1);
3831+
memcpy(bod->contents.text.data, "", 1);
3832+
bod->contents.text.size = 0;
3833+
}
38303834
}
38313835
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "lines", sizeof("lines") - 1)) != NULL) {
38323836
bod->size.lines = zval_get_long(pvalue);
@@ -3927,7 +3931,7 @@ PHP_FUNCTION(imap_mail_compose)
39273931

39283932
bod=&part->body;
39293933

3930-
spprintf(&tempstring, 0, "%s%s%s", mystring, bod->contents.text.data, CRLF);
3934+
spprintf(&tempstring, 0, "%s%s%s", mystring, bod->contents.text.data ? (char *) bod->contents.text.data : "", CRLF);
39313935
efree(mystring);
39323936
mystring=tempstring;
39333937
} while ((part = part->next)); /* until done */

ext/imap/tests/bug80242.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Bug #80242 (imap_mail_compose() segfaults for multipart with rfc822)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('imap')) die('skip imap extension not available');
6+
?>
7+
--FILE--
8+
<?php
9+
$bodies = [[
10+
'type' => TYPEMULTIPART,
11+
], [
12+
'type' => TYPETEXT,
13+
'contents.data' => 'some text',
14+
], [
15+
'type' => TYPEMESSAGE,
16+
'subtype' => 'RFC822',
17+
]];
18+
imap_mail_compose([], $bodies);
19+
echo "done\n";
20+
?>
21+
--EXPECT--
22+
done

0 commit comments

Comments
 (0)