Skip to content

Commit

Permalink
oxcmail: do not ignore IDN addresses when reading headers
Browse files Browse the repository at this point in the history
vmime converts incoming addrspecs from punycoded to UTF-8
irrespective of parsingContext::getInternationalizedEmailSupport()
yielding any particular value. Of course then they are not ASCII
anymore, leading to those addresses having gotten ignored in
oxcmail_parse_reply_to.
  • Loading branch information
jengelh committed Jan 30, 2024
1 parent ce933ab commit f139948
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 11 deletions.
12 changes: 9 additions & 3 deletions lib/mail_func.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,15 @@ void parse_mime_addr(EMAIL_ADDR *e_addr, const char *input) try
mb.parse(input);

gx_strlcpy(e_addr->display_name, mb.getName().getConvertedText("utf-8").c_str(), std::size(e_addr->display_name));
auto &emp = mb.getEmail();
gx_strlcpy(e_addr->local_part, emp.getLocalName().getConvertedText("utf-8").c_str(), std::size(e_addr->local_part));
gx_strlcpy(e_addr->domain, emp.getDomainName().getConvertedText("utf-8").c_str(), std::size(e_addr->domain));
auto emp = mb.getEmail().generate();
auto at = emp.find('@');
if (at == emp.npos) {
*e_addr = {};
return;
}
emp[at] = '\0';
gx_strlcpy(e_addr->local_part, &emp[0], std::size(e_addr->local_part));
gx_strlcpy(e_addr->domain, &emp[at+1], std::size(e_addr->domain));
} catch (const std::bad_alloc &) {
*e_addr = {};
}
Expand Down
29 changes: 21 additions & 8 deletions lib/mapi/oxcmail.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ static BOOL oxcmail_parse_recipient(const char *charset,
}

static BOOL oxcmail_parse_addresses(const char *charset, const char *field,
uint32_t rcpt_type, TARRAY_SET *pset)
uint32_t rcpt_type, TARRAY_SET *pset) try
{
EMAIL_ADDR email_addr;

Expand All @@ -503,17 +503,26 @@ static BOOL oxcmail_parse_addresses(const char *charset, const char *field,
if (mb == nullptr)
continue;
gx_strlcpy(email_addr.display_name, mb->getName().getConvertedText("utf-8").c_str(), std::size(email_addr.display_name));
auto &emp = mb->getEmail();
gx_strlcpy(email_addr.local_part, emp.getLocalName().getConvertedText("utf-8").c_str(), std::size(email_addr.local_part));
gx_strlcpy(email_addr.domain, emp.getDomainName().getConvertedText("utf-8").c_str(), std::size(email_addr.domain));
auto emp = mb->getEmail().generate();
auto at = emp.find('@');
if (at == emp.npos)
continue;
emp[at] = '\0';
gx_strlcpy(email_addr.local_part, &emp[0], std::size(email_addr.local_part));
gx_strlcpy(email_addr.domain, &emp[at+1], std::size(email_addr.domain));

if (*email_addr.local_part == '\0')
if (!email_addr.has_addr() ||
!oxcmail_is_ascii(email_addr.local_part) ||
!oxcmail_is_ascii(email_addr.domain))
continue;
if (!oxcmail_parse_recipient(charset,
&email_addr, rcpt_type, pset))
return FALSE;
}
return TRUE;
} catch (const std::bad_alloc &) {
mlog(LV_ERR, "E-2047: ENOMEM");
return false;
}

static BOOL oxcmail_parse_address(const char *field,
Expand Down Expand Up @@ -602,9 +611,13 @@ static BOOL oxcmail_parse_reply_to(const char *charset, const char *field,
if (mb == nullptr)
continue;
gx_strlcpy(email_addr.display_name, mb->getName().getConvertedText("utf-8").c_str(), std::size(email_addr.display_name));
auto &emp = mb->getEmail();
gx_strlcpy(email_addr.local_part, emp.getLocalName().getConvertedText("utf-8").c_str(), std::size(email_addr.local_part));
gx_strlcpy(email_addr.domain, emp.getDomainName().getConvertedText("utf-8").c_str(), std::size(email_addr.domain));
auto emp = mb->getEmail().generate();
auto at = emp.find('@');
if (at == emp.npos)
continue;
emp[at] = '\0';
gx_strlcpy(email_addr.local_part, &emp[0], std::size(email_addr.local_part));
gx_strlcpy(email_addr.domain, &emp[at+1], std::size(email_addr.domain));

if (!email_addr.has_addr() ||
!oxcmail_is_ascii(email_addr.local_part) ||
Expand Down

0 comments on commit f139948

Please sign in to comment.