From: R. David Murray Date: Sat, 2 Oct 2010 16:04:44 +0000 (+0000) Subject: Merged revisions 85179 via svnmerge from X-Git-Tag: v3.1.3rc1~177 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7f8199a9979c9f100d754d4910d5e1bd6f929d9a;p=python Merged revisions 85179 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r85179 | r.david.murray | 2010-10-02 11:58:26 -0400 (Sat, 02 Oct 2010) | 6 lines #1050268: make parseaddr 'quote' the contents of quoted strings in addresses. Also made the doc string for email._parseaddr's 'quote' function more accurate; I'd love to make the function match the old docstring instead, but other code uses it according the existing semantics. ........ --- diff --git a/Lib/email/_parseaddr.py b/Lib/email/_parseaddr.py index ac2e524401..3bd4ba4403 100644 --- a/Lib/email/_parseaddr.py +++ b/Lib/email/_parseaddr.py @@ -160,7 +160,12 @@ def mktime_tz(data): def quote(str): - """Add quotes around a string.""" + """Prepare string to be used in a quoted string. + + Turns backslash and double quote characters into quoted pairs. These + are the only characters that need to be quoted inside a quoted string. + Does not add the surrounding double quotes. + """ return str.replace('\\', '\\\\').replace('"', '\\"') @@ -318,7 +323,7 @@ class AddrlistClass: aslist.append('.') self.pos += 1 elif self.field[self.pos] == '"': - aslist.append('"%s"' % self.getquote()) + aslist.append('"%s"' % quote(self.getquote())) elif self.field[self.pos] in self.atomends: break else: diff --git a/Lib/email/test/test_email.py b/Lib/email/test/test_email.py index 42a2ee3b2f..e8dfbbc65e 100644 --- a/Lib/email/test/test_email.py +++ b/Lib/email/test/test_email.py @@ -2283,6 +2283,24 @@ class TestMiscellaneous(TestEmailBase): # formataddr() quotes the name if there's a dot in it self.assertEqual(utils.formataddr((a, b)), y) + def test_parseaddr_preserves_quoted_pairs_in_addresses(self): + # issue 10005. Note that in the third test the second pair of + # backslashes is not actually a quoted pair because it is not inside a + # comment or quoted string: the address being parsed has a quoted + # string containing a quoted backslash, followed by 'example' and two + # backslashes, followed by another quoted string containing a space and + # the word 'example'. parseaddr copies those two backslashes + # literally. Per rfc5322 this is not technically correct since a \ may + # not appear in an address outside of a quoted string. It is probably + # a sensible Postel interpretation, though. + eq = self.assertEqual + eq(utils.parseaddr('""example" example"@example.com'), + ('', '""example" example"@example.com')) + eq(utils.parseaddr('"\\"example\\" example"@example.com'), + ('', '"\\"example\\" example"@example.com')) + eq(utils.parseaddr('"\\\\"example\\\\" example"@example.com'), + ('', '"\\\\"example\\\\" example"@example.com')) + def test_multiline_from_comment(self): x = """\ Foo diff --git a/Misc/NEWS b/Misc/NEWS index 8781c0028c..d9d4a0e364 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -121,6 +121,9 @@ C-API Library ------- +- Issue #1050268: parseaddr now correctly quotes double quote and backslash + characters that appear inside quoted strings in email addresses. + - Issue #10004: quoprimime no longer generates a traceback when confronted with invalid characters after '=' in a Q-encoded word.