[PECL-CVS] [pecl-mail-mailparse] master: Reject non-mimepart resources in mailparse_msg_* instead of crashing

[email protected] (Ilia Alshanetsky via Remi Collet) Wed, 24 Jun 2026 08:09:24 +0000
Newsgroups php.pecl.cvs
Message-ID <[email protected]>
Author: Ilia Alshanetsky (iliaal)
Committer: Remi Collet (remicollet)
Date: 2026-06-24T10:06:47+02:00

Commit: https://github.com/php/pecl-mail-mailparse/commit/984db5887ae3c34638b86f76ebe1ef1542e1decf
Raw diff: https://github.com/php/pecl-mail-mailparse/commit/984db5887ae3c34638b86f76ebe1ef1542e1decf.diff

Reject non-mimepart resources in mailparse_msg_* instead of crashing

Changed paths:
  A  tests/msg_funcs_reject_wrong_resource.phpt
  M  mailparse.c


Diff:

diff --git a/mailparse.c b/mailparse.c
index b690f9e..6210be0 100644
--- a/mailparse.c
+++ b/mailparse.c
@@ -1086,6 +1086,9 @@ PHP_FUNCTION(mailparse_msg_parse)
 	}
 
 	mailparse_fetch_mimepart_resource(part, arg);
+	if (part == NULL) {
+		RETURN_FALSE;
+	}
 
 	if (FAILURE == php_mimepart_parse(part, ZSTR_VAL(data), ZSTR_LEN(data))) {
 		RETURN_FALSE;
@@ -1189,6 +1192,9 @@ PHP_FUNCTION(mailparse_msg_get_structure)
 	}
 
 	mailparse_fetch_mimepart_resource(part, arg);
+	if (part == NULL) {
+		RETURN_FALSE;
+	}
 
 	array_init(return_value);
 	php_mimepart_enum_parts(part, &get_structure_callback, return_value);
@@ -1314,6 +1320,9 @@ static void mailparse_do_extract(INTERNAL_FUNCTION_PARAMETERS, int decode, int i
 	}
 
 	mailparse_fetch_mimepart_resource(part, zpart);
+	if (part == NULL) {
+		RETURN_FALSE;
+	}
 
 	/* filename can be a filename or a stream */
 	if (Z_TYPE_P(filename) == IS_RESOURCE) {
@@ -1574,6 +1583,9 @@ PHP_FUNCTION(mailparse_msg_get_part_data)
 	}
 
 	mailparse_fetch_mimepart_resource(part, arg);
+	if (part == NULL) {
+		RETURN_FALSE;
+	}
 
 	mailparse_get_part_data(part, return_value);
 }
@@ -1592,6 +1604,9 @@ PHP_FUNCTION(mailparse_msg_get_part)
 	}
 
 	mailparse_fetch_mimepart_resource(part, arg);
+	if (part == NULL) {
+		RETURN_FALSE;
+	}
 
 	foundpart = php_mimepart_find_by_name(part, ZSTR_VAL(mimesection));
 
diff --git a/tests/msg_funcs_reject_wrong_resource.phpt b/tests/msg_funcs_reject_wrong_resource.phpt
new file mode 100644
index 0000000..92f035d
--- /dev/null
+++ b/tests/msg_funcs_reject_wrong_resource.phpt
@@ -0,0 +1,26 @@
+--TEST--
+mailparse_msg_* reject a non-mimepart resource instead of crashing
+--SKIPIF--
+<?php if (!extension_loaded("mailparse")) print "skip"; ?>
+--FILE--
+<?php
+/* Passing a wrong-type resource (a plain stream handle) used to dereference a
+ * NULL mimepart and segfault. It must now fail cleanly: a TypeError on PHP 8,
+ * a warning + false on PHP 7. Either way the process survives. */
+$fp = tmpfile();
+
+foreach (array("mailparse_msg_parse", "mailparse_msg_get_structure",
+		"mailparse_msg_get_part_data", "mailparse_msg_get_part",
+		"mailparse_msg_extract_part") as $fn) {
+	try {
+		@$fn($fp, "x");
+	} catch (\Throwable $e) {
+		/* TypeError on PHP 8 */
+	}
+}
+
+fclose($fp);
+echo "survived\n";
+?>
+--EXPECT--
+survived