* @param[out] domain Domain
* @retval 0 Success
* @retval -1 Error
+ *
+ * @warning The caller must free user and domain
*/
int mutt_addr_mbox_to_udomain(const char *mbox, char **user, char **domain)
{
- static char *buf = NULL;
- char *p = NULL;
+ char *ptr = strchr(mbox, '@');
- mutt_str_replace(&buf, mbox);
- if (!buf)
+ /* Fail if '@' is missing, at the start, or at the end */
+ if (!ptr || (ptr == mbox) || (ptr[1] == '\0'))
return -1;
- p = strchr(buf, '@');
- if (!p || !p[1])
- return -1;
- *p = '\0';
- *user = buf;
- *domain = p + 1;
+ *user = mutt_str_substr_dup(mbox, ptr);
+ *domain = mutt_str_strdup(ptr + 1);
+
return 0;
}
return a->mailbox;
local_mailbox = mutt_idna_intl_to_local(user, domain, MI_MAY_BE_IRREVERSIBLE);
+
+ FREE(&user);
+ FREE(&domain);
+
if (!local_mailbox)
+ {
return a->mailbox;
+ }
mutt_str_replace(&buf, local_mailbox);
FREE(&local_mailbox);
+
return buf;
}
continue;
intl_mailbox = mutt_idna_local_to_intl(user, domain);
+
+ FREE(&user);
+ FREE(&domain);
+
if (!intl_mailbox)
{
rc = -1;
continue;
local_mailbox = mutt_idna_intl_to_local(user, domain, 0);
+
+ FREE(&user);
+ FREE(&domain);
+
if (local_mailbox)
mutt_addr_set_local(a, local_mailbox);
}
--- /dev/null
+#define TEST_NO_MAIN
+#include "acutest.h"
+#include "acutest.h"
+#include "email/address.h"
+#include "mutt/memory.h"
+#include <string.h>
+
+#define TEST_CHECK_STR_EQ(expected, actual) \
+ do \
+ { \
+ if (!TEST_CHECK(strcmp(expected, actual) == 0)) \
+ { \
+ TEST_MSG("Expected: %s", expected); \
+ TEST_MSG("Actual : %s", actual); \
+ } \
+ } while (false)
+
+void test_addr_mbox_to_udomain(void)
+{
+ { /* edge cases */
+ char *user = NULL;
+ char *domain = NULL;
+
+ if (!TEST_CHECK(mutt_addr_mbox_to_udomain("bobnodomain@", &user, &domain) == -1) ||
+ !TEST_CHECK(mutt_addr_mbox_to_udomain("bobnodomain", &user, &domain) == -1) ||
+ !TEST_CHECK(mutt_addr_mbox_to_udomain("@nobobohnoez", &user, &domain) == -1) ||
+ !TEST_CHECK(mutt_addr_mbox_to_udomain("", &user, &domain) == -1))
+ {
+ TEST_MSG("bad return");
+ }
+ }
+
+ { /* common */
+ int ret = 0;
+ const char *str = "bob@bobsdomain";
+
+ char *user = NULL;
+ char *domain = NULL;
+ ret = mutt_addr_mbox_to_udomain(str, &user, &domain);
+
+ if (!TEST_CHECK(ret == 0))
+ {
+ TEST_MSG("bad return");
+ TEST_MSG("Expected: %d", 0);
+ TEST_MSG("Actual : %d", ret);
+ }
+
+ TEST_CHECK_STR_EQ("bob", user);
+ TEST_CHECK_STR_EQ("bobsdomain", domain);
+
+ FREE(&user);
+ FREE(&domain);
+ }
+
+ { /* integration */
+ char buf[256] = { 0 };
+ char *per = "bobby bob";
+ char *mbx = "bob@bobsdomain";
+
+ struct Address addr = {
+ .personal = per,
+ .mailbox = mbx,
+ .group = 0,
+ .next = NULL,
+ .is_intl = 0,
+ .intl_checked = 0,
+ };
+
+ mutt_addr_write_single(buf, sizeof(buf), &addr, false);
+
+ const char *expected = "bobby bob <bob@bobsdomain>";
+
+ TEST_CHECK_STR_EQ(expected, buf);
+ }
+
+ { /* integration */
+ char *per = "bobby bob";
+ char *mbx = "bob@bobsdomain";
+
+ struct Address addr = {
+ .personal = per,
+ .mailbox = mbx,
+ .group = 0,
+ .next = NULL,
+ .is_intl = 0,
+ .intl_checked = 0,
+ };
+
+ const char *expected = "bob@bobsdomain";
+ const char *actual = mutt_addr_for_display(&addr);
+
+ TEST_CHECK_STR_EQ(expected, actual);
+ }
+}
NEOMUTT_TEST_ITEM(test_md5_ctx) \
NEOMUTT_TEST_ITEM(test_md5_ctx_bytes) \
NEOMUTT_TEST_ITEM(test_string_strfcpy) \
- NEOMUTT_TEST_ITEM(test_string_strnfcpy)
+ NEOMUTT_TEST_ITEM(test_string_strnfcpy) \
+ NEOMUTT_TEST_ITEM(test_addr_mbox_to_udomain)
/******************************************************************************
* You probably don't need to touch what follows.