[FIX] base: make extract_rfc2822_addresses more robust
If source is something like "admin@éxample.com" <admin@éxample.com> candidates founds are ['"admin@\xc3\xa9xample.com"', 'admin@\xc3\xa9xample.com'] and the first one raises an error because of "". Malformed addresses should be ignored. opw-2982426 closes odoo/odoo#102353 X-original-commit: 35ad2dd630a8ed173c6a9275585eac46b9a19363 Signed-off-by: Raphael Collet <rco@odoo.com> Signed-off-by: Julien Castiaux <juc@odoo.com>
This commit is contained in:
@@ -293,10 +293,10 @@ class TestMailMail(TestMailCommon):
|
||||
with self.mock_mail_gateway():
|
||||
mail.send(raise_exception=False)
|
||||
self.assertEqual(self._mails[0]['email_from'], 'strange@example¢¡.com')
|
||||
self.assertIn('Codepoint U+00A2 at position', mail.failure_reason)
|
||||
self.assertEqual(mail.failure_reason, "Malformed 'Return-Path' or 'From' address: strange@example¢¡.com - It should contain one valid plain ASCII email")
|
||||
self.assertFalse(mail.failure_type, 'Mail: bugged from (ascii): no failure type, should be updated')
|
||||
self.assertEqual(mail.state, 'exception')
|
||||
self.assertIn('Codepoint U+00A2 at position', notification.failure_reason)
|
||||
self.assertEqual(notification.failure_reason, "Malformed 'Return-Path' or 'From' address: strange@example¢¡.com - It should contain one valid plain ASCII email")
|
||||
self.assertEqual(notification.failure_type, 'unknown', 'Mail: bugged from (ascii): unknown failure type, should be updated')
|
||||
self.assertEqual(notification.notification_status, 'exception')
|
||||
|
||||
@@ -307,10 +307,10 @@ class TestMailMail(TestMailCommon):
|
||||
with self.mock_mail_gateway():
|
||||
mail.send(raise_exception=False)
|
||||
self.assertEqual(self._mails[0]['email_from'], 'test.user@example.com')
|
||||
self.assertIn('Codepoint U+00A2 at position', mail.failure_reason)
|
||||
self.assertIn("Malformed 'Return-Path' or 'From' address: bounce.test@domain¢¡.com", mail.failure_reason)
|
||||
self.assertFalse(mail.failure_type, 'Mail: bugged catchall domain (ascii): no failure type, should be updated')
|
||||
self.assertEqual(mail.state, 'exception')
|
||||
self.assertIn('Codepoint U+00A2 at position', notification.failure_reason)
|
||||
self.assertEqual(notification.failure_reason, "Malformed 'Return-Path' or 'From' address: bounce.test@domain¢¡.com - It should contain one valid plain ASCII email")
|
||||
self.assertEqual(notification.failure_type, 'unknown', 'Mail: bugged catchall domain (ascii): unknown failure type, should be updated')
|
||||
self.assertEqual(notification.notification_status, 'exception')
|
||||
|
||||
@@ -375,11 +375,10 @@ class TestMailMail(TestMailCommon):
|
||||
mail.write({'email_to': email_to})
|
||||
with self.mock_mail_gateway():
|
||||
mail.send(raise_exception=False)
|
||||
self.assertIn('Codepoint U+00A2 at position', mail.failure_reason)
|
||||
self.assertEqual(mail.failure_reason, 'Error without exception. Probably due to sending an email without computed recipients.')
|
||||
self.assertFalse(mail.failure_type, 'Mail: invalid (ascii) recipient partner: no failure type, should be updated')
|
||||
self.assertEqual(mail.state, 'exception')
|
||||
self.assertIn('Codepoint U+00A2 at position', notification.failure_reason)
|
||||
self.assertEqual(notification.failure_type, 'unknown', 'Mail: invalid (ascii) recipient partner: unknown failure type, should be updated')
|
||||
self.assertEqual(notification.failure_type, 'mail_email_invalid')
|
||||
self.assertEqual(notification.notification_status, 'exception')
|
||||
|
||||
# MailServer.send_email(): _prepare_email_message: ok To (ascii or just ok)
|
||||
@@ -454,11 +453,10 @@ class TestMailMail(TestMailCommon):
|
||||
notification.write({'res_partner_id': partner.id})
|
||||
with self.mock_mail_gateway():
|
||||
mail.send(raise_exception=False)
|
||||
self.assertIn('Codepoint U+00A2 at position', mail.failure_reason)
|
||||
self.assertEqual(mail.failure_reason, 'Error without exception. Probably due to sending an email without computed recipients.')
|
||||
self.assertFalse(mail.failure_type, 'Mail: invalid (ascii) recipient partner: no failure type, should be updated')
|
||||
self.assertEqual(mail.state, 'exception')
|
||||
self.assertIn('Codepoint U+00A2 at position', notification.failure_reason)
|
||||
self.assertEqual(notification.failure_type, 'unknown', 'Mail: invalid (ascii) recipient partner: unknown failure type, should be updated')
|
||||
self.assertEqual(notification.failure_type, 'mail_email_invalid')
|
||||
self.assertEqual(notification.notification_status, 'exception')
|
||||
|
||||
# ascii ok or just ok
|
||||
@@ -544,14 +542,12 @@ class TestMailMail(TestMailCommon):
|
||||
mail.write({'email_to': email_to})
|
||||
with self.mock_mail_gateway():
|
||||
mail.send(raise_exception=False)
|
||||
self.assertIn('Codepoint U+00A2 at position', mail.failure_reason)
|
||||
|
||||
self.assertFalse(mail.failure_type, 'Mail: at least one valid recipient, mail is sent to avoid send loops and spam')
|
||||
self.assertEqual(mail.state, 'exception')
|
||||
self.assertIn('Codepoint U+00A2 at position', notification.failure_reason)
|
||||
self.assertEqual(notification.failure_type, 'unknown')
|
||||
self.assertEqual(notification.notification_status, 'exception')
|
||||
self.assertIn('Codepoint U+00A2 at position', notification2.failure_reason)
|
||||
self.assertEqual(notification2.failure_type, 'unknown')
|
||||
self.assertEqual(mail.state, 'sent')
|
||||
self.assertFalse(notification.failure_type)
|
||||
self.assertEqual(notification.notification_status, 'sent')
|
||||
self.assertEqual(notification2.failure_type, 'mail_email_invalid')
|
||||
self.assertEqual(notification2.notification_status, 'exception')
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_mail')
|
||||
|
||||
@@ -815,7 +815,7 @@ class TestMailComplexPerformance(BaseMailPerformance):
|
||||
'mail_server_id': self.mail_servers.ids[idx % len(self.mail_servers.ids)],
|
||||
'recipient_ids': [(4, pid) for pid in self.partners.ids],
|
||||
} for idx in range(12)])
|
||||
mails[-2].write({'email_cc': False, 'email_to': 'strange@example¢¡.com'})
|
||||
mails[-2].write({'email_cc': False, 'email_to': 'strange@example¢¡.com', 'recipient_ids': [(5, 0)]})
|
||||
mails[-1].write({'email_cc': False, 'email_to': 'void', 'recipient_ids': [(5, 0)]})
|
||||
with self.assertQueryCount(__system__=44, employee=44):
|
||||
self.env['mail.mail'].sudo().browse(mails.ids).send()
|
||||
@@ -824,9 +824,9 @@ class TestMailComplexPerformance(BaseMailPerformance):
|
||||
self.assertEqual(mail.state, 'sent')
|
||||
self.assertTrue(mail.to_delete, 'Mail: sent mails are to be unlinked')
|
||||
self.assertEqual(mails[-2].state, 'exception')
|
||||
self.assertFalse(mails[-2].to_delete, 'Mail: invalid recipient, not to unlink')
|
||||
self.assertTrue(mails[-2].to_delete, 'Mail: mails with invalid recipient are also to be unlinked')
|
||||
self.assertEqual(mails[-1].state, 'exception')
|
||||
self.assertFalse(mails[-2].to_delete, 'Mail: ninvalid recipient, not to unlink')
|
||||
self.assertTrue(mails[-1].to_delete, 'Mail: mails with invalid recipient are also to be unlinked')
|
||||
|
||||
@mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
|
||||
@users('__system__', 'employee')
|
||||
|
||||
@@ -75,7 +75,13 @@ def extract_rfc2822_addresses(text):
|
||||
if not text:
|
||||
return []
|
||||
candidates = address_pattern.findall(ustr(text))
|
||||
return [formataddr(('', c), charset='ascii') for c in candidates]
|
||||
valid_addresses = []
|
||||
for c in candidates:
|
||||
try:
|
||||
valid_addresses.append(formataddr(('', c), charset='ascii'))
|
||||
except idna.IDNAError:
|
||||
pass
|
||||
return valid_addresses
|
||||
|
||||
|
||||
class IrMailServer(models.Model):
|
||||
|
||||
@@ -452,6 +452,7 @@ class TestEmailTools(BaseCase):
|
||||
('admin@example.com', ['admin@example.com']),
|
||||
('"Admin" <admin@example.com>, Demo <malformed email>', ['admin@example.com']),
|
||||
('admin@éxample.com', ['admin@xn--xample-9ua.com']),
|
||||
('"admin@éxample.com" <admin@éxample.com>', ['admin@xn--xample-9ua.com']),
|
||||
]
|
||||
|
||||
for (rfc2822_email, expected) in tests:
|
||||
|
||||
Reference in New Issue
Block a user