]> granicus.if.org Git - python/commitdiff
Merged revisions 85179 via svnmerge from
authorR. David Murray <rdmurray@bitdance.com>
Sat, 2 Oct 2010 16:04:44 +0000 (16:04 +0000)
committerR. David Murray <rdmurray@bitdance.com>
Sat, 2 Oct 2010 16:04:44 +0000 (16:04 +0000)
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.
........

Lib/email/_parseaddr.py
Lib/email/test/test_email.py
Misc/NEWS

index ac2e524401e327fe31170a011ae69049d602d419..3bd4ba44030e426a32be73c49d4aed1b21f7c7ed 100644 (file)
@@ -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:
index 42a2ee3b2fa8dee5ef09658b83ab9fd6ba21373c..e8dfbbc65e4475335f0226d7ee1e594830ddcc6d 100644 (file)
@@ -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
index 8781c0028cd06ec878f5f6edcfa7ca88b4bfd9f3..d9d4a0e3648f2e9d53e1c3f256b87c576bfd6175 100644 (file)
--- 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.