Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1fb22bb

Browse files
committed
Port rfc822.py changes that didn't make it into this copy,
specifically that dots are allowed in obs-phrase. This fixes parsing of dots in realnames.
1 parent edb59c1 commit 1fb22bb

1 file changed

Lines changed: 35 additions & 21 deletions

File tree

Lib/email/_parseaddr.py

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ def quote(str):
135135
class AddrlistClass:
136136
"""Address parser class by Ben Escoto.
137137
138-
To understand what this class does, it helps to have a copy of
139-
RFC-822 in front of you.
138+
To understand what this class does, it helps to have a copy of RFC 2822 in
139+
front of you.
140140
141141
Note: this class interface is deprecated and may be removed in the future.
142142
Use rfc822.AddressList instead.
@@ -153,6 +153,10 @@ def __init__(self, field):
153153
self.LWS = ' \t'
154154
self.CR = '\r\n'
155155
self.atomends = self.specials + self.LWS + self.CR
156+
# Note that RFC 2822 now specifies `.' as obs-phrase, meaning that it
157+
# is obsolete syntax. RFC 2822 requires that we recognize obsolete
158+
# syntax, so allow dots in phrases.
159+
self.phraseends = self.atomends.replace('.', '')
156160
self.field = field
157161
self.commentlist = []
158162

@@ -170,10 +174,14 @@ def getaddrlist(self):
170174
171175
Returns a list containing all of the addresses.
172176
"""
173-
ad = self.getaddress()
174-
if ad:
175-
return ad + self.getaddrlist()
176-
else: return []
177+
result = []
178+
while 1:
179+
ad = self.getaddress()
180+
if ad:
181+
result += ad
182+
else:
183+
break
184+
return result
177185

178186
def getaddress(self):
179187
"""Parse the next address."""
@@ -257,7 +265,6 @@ def getrouteaddr(self):
257265
expectroute = 1
258266
elif self.field[self.pos] == ':':
259267
self.pos = self.pos + 1
260-
expectaddrspec = 1
261268
else:
262269
adlist = self.getaddrspec()
263270
self.pos = self.pos + 1
@@ -267,7 +274,7 @@ def getrouteaddr(self):
267274
return adlist
268275

269276
def getaddrspec(self):
270-
"""Parse an RFC-822 addr-spec."""
277+
"""Parse an RFC 2822 addr-spec."""
271278
aslist = []
272279

273280
self.gotonext()
@@ -318,8 +325,8 @@ def getdelimited(self, beginchar, endchars, allowcomments = 1):
318325
`endchars' is a sequence of allowable end-delimiting characters.
319326
Parsing stops when one of these is encountered.
320327
321-
If `allowcomments' is non-zero, embedded RFC-822 comments
322-
are allowed within the parsed fragment.
328+
If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed
329+
within the parsed fragment.
323330
"""
324331
if self.field[self.pos] != beginchar:
325332
return ''
@@ -353,27 +360,34 @@ def getcomment(self):
353360
return self.getdelimited('(', ')\r', 1)
354361

355362
def getdomainliteral(self):
356-
"""Parse an RFC-822 domain-literal."""
363+
"""Parse an RFC 2822 domain-literal."""
357364
return '[%s]' % self.getdelimited('[', ']\r', 0)
358365

359-
def getatom(self):
360-
"""Parse an RFC-822 atom."""
366+
def getatom(self, atomends=None):
367+
"""Parse an RFC 2822 atom.
368+
369+
Optional atomends specifies a different set of end token delimiters
370+
(the default is to use self.atomends). This is used e.g. in
371+
getphraselist() since phrase endings must not include the `.' (which
372+
is legal in phrases)."""
361373
atomlist = ['']
374+
if atomends is None:
375+
atomends = self.atomends
362376

363377
while self.pos < len(self.field):
364-
if self.field[self.pos] in self.atomends:
378+
if self.field[self.pos] in atomends:
365379
break
366380
else: atomlist.append(self.field[self.pos])
367381
self.pos = self.pos + 1
368382

369383
return ''.join(atomlist)
370384

371385
def getphraselist(self):
372-
"""Parse a sequence of RFC-822 phrases.
386+
"""Parse a sequence of RFC 2822 phrases.
373387
374-
A phrase is a sequence of words, which are in turn either
375-
RFC-822 atoms or quoted-strings. Phrases are canonicalized
376-
by squeezing all runs of continuous whitespace into one space.
388+
A phrase is a sequence of words, which are in turn either RFC 2822
389+
atoms or quoted-strings. Phrases are canonicalized by squeezing all
390+
runs of continuous whitespace into one space.
377391
"""
378392
plist = []
379393

@@ -384,14 +398,14 @@ def getphraselist(self):
384398
plist.append(self.getquote())
385399
elif self.field[self.pos] == '(':
386400
self.commentlist.append(self.getcomment())
387-
elif self.field[self.pos] in self.atomends:
401+
elif self.field[self.pos] in self.phraseends:
388402
break
389-
else: plist.append(self.getatom())
403+
else: plist.append(self.getatom(self.phraseends))
390404

391405
return plist
392406

393407
class AddressList(AddrlistClass):
394-
"""An AddressList encapsulates a list of parsed RFC822 addresses."""
408+
"""An AddressList encapsulates a list of parsed RFC 2822 addresses."""
395409
def __init__(self, field):
396410
AddrlistClass.__init__(self, field)
397411
if field:

0 commit comments

Comments
 (0)