Commit fccb7cb367 for asterisk.org

commit fccb7cb367bd44014fe08c5d1451530c465f9de7
Author: aabolfazl <aabolfazlit@gmail.com>
Date:   Sun Aug 9 20:38:48 2026 +0300

    app_voicemail: Fix crash when VM_INFO reads an unset email address.

    The email member of struct ast_vm_user is a pointer rather than a fixed
    array, and populate_defaults() leaves it NULL when a mailbox has no
    email address configured. Every other attribute VM_INFO reads is a fixed
    array, so only the email attribute is affected.

    VM_INFO passed vmu->email straight to ast_copy_string(), which
    dereferences its source unconditionally. Reading the email attribute of
    a mailbox that has no email address therefore crashed Asterisk from the
    dialplan.

    Guard the copy with S_OR() so an unset email address yields an empty
    string, matching how the language attribute already handles its
    fallback. The make_email_file() call sites were already guarded and are
    left alone.

    Add a regression test for the unset case, and restore the voicemail
    configuration when the VM_INFO test finishes. That test was the only one
    in app_voicemail that did not do so, which left its test mailbox in the
    users list and made the test fail if it ran a second time.

    Fixes: #2063

diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 9a3275d0a4..258d294471 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -13658,7 +13658,7 @@ static int acf_vm_info(struct ast_channel *chan, const char *cmd, char *args, ch
 		} else if (!strncasecmp(arg.attribute, "fullname", 8)) {
 			ast_copy_string(buf, vmu->fullname, len);
 		} else if (!strncasecmp(arg.attribute, "email", 5)) {
-			ast_copy_string(buf, vmu->email, len);
+			ast_copy_string(buf, S_OR(vmu->email, ""), len);
 		} else if (!strncasecmp(arg.attribute, "pager", 5)) {
 			ast_copy_string(buf, vmu->pager, len);
 		} else if (!strncasecmp(arg.attribute, "language", 8)) {
@@ -16132,8 +16132,23 @@ AST_TEST_DEFINE(test_voicemail_vm_info)
 		}
 	}

+	ast_free(vmu->email);
+	vmu->email = NULL;
+
+	ast_copy_string(vminfo_args, "00000000@test,email", sizeof(vminfo_args));
+	test_ret = acf_vm_info(chan, vminfo_cmd, vminfo_args, vminfo_buf, sizeof(vminfo_buf));
+	if (!ast_strlen_zero(vminfo_buf)) {
+		ast_test_status_update(test, "VM_INFO response for a mailbox without an email address was: '%s', but expected: ''\n", vminfo_buf);
+		res = AST_TEST_FAIL;
+	}
+	if (test_ret != 0) {
+		ast_test_status_update(test, "VM_INFO return code for a mailbox without an email address was: '%i', but expected '0'\n", test_ret);
+		res = AST_TEST_FAIL;
+	}
+
 	chan = ast_channel_unref(chan);
 	free_user(vmu);
+	force_reload_config(); /* Restore original config */
 	return res;
 }
 #endif /* defined(TEST_FRAMEWORK) */