Mercurial > cpython-lru_cache-weakref
annotate Lib/email/header.py @ 79691:05c8928362ee
Merge __next__ method link fixes with 3.3.
| author | Ezio Melotti <ezio.melotti@gmail.com> |
|---|---|
| date | Fri, 12 Oct 2012 13:46:37 +0300 |
| parents | 8c03fe231877 |
| children | 15a391919deb |
| rev | line source |
|---|---|
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
1 # Copyright (C) 2002-2007 Python Software Foundation |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
2 # Author: Ben Gertzfield, Barry Warsaw |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
3 # Contact: email-sig@python.org |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
4 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
5 """Header encoding and decoding functionality.""" |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
6 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
7 __all__ = [ |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
8 'Header', |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
9 'decode_header', |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
10 'make_header', |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
11 ] |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
12 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
13 import re |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
14 import binascii |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
15 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
16 import email.quoprimime |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
17 import email.base64mime |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
18 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
19 from email.errors import HeaderParseError |
|
67447
cad1811d9e13
#10686: recode non-ASCII headers to 'unknown-8bit' instead of ?s.
R. David Murray <rdmurray@bitdance.com>
parents:
67446
diff
changeset
|
20 from email import charset as _charset |
|
cad1811d9e13
#10686: recode non-ASCII headers to 'unknown-8bit' instead of ?s.
R. David Murray <rdmurray@bitdance.com>
parents:
67446
diff
changeset
|
21 Charset = _charset.Charset |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
22 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
23 NL = '\n' |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
24 SPACE = ' ' |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
25 BSPACE = b' ' |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
26 SPACE8 = ' ' * 8 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
27 EMPTYSTRING = '' |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
28 MAXLINELEN = 78 |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
29 FWS = ' \t' |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
30 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
31 USASCII = Charset('us-ascii') |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
32 UTF8 = Charset('utf-8') |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
33 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
34 # Match encoded-word strings in the form =?charset?q?Hello_World?= |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
35 ecre = re.compile(r''' |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
36 =\? # literal =? |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
37 (?P<charset>[^?]*?) # non-greedy up to the next ? is the charset |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
38 \? # literal ? |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
39 (?P<encoding>[qb]) # either a "q" or a "b", case insensitive |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
40 \? # literal ? |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
41 (?P<encoded>.*?) # non-greedy up to the next ?= is the encoded string |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
42 \?= # literal ?= |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
43 ''', re.VERBOSE | re.IGNORECASE | re.MULTILINE) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
44 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
45 # Field name regexp, including trailing colon, but not separating whitespace, |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
46 # according to RFC 2822. Character range is from tilde to exclamation mark. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
47 # For use with .match() |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
48 fcre = re.compile(r'[\041-\176]+:$') |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
49 |
|
68585
bf94b6a73fc8
#11565: Fix several typos. Patch by Piotr Kasprzyk.
Ezio Melotti <ezio.melotti@gmail.com>
parents:
67917
diff
changeset
|
50 # Find a header embedded in a putative header value. Used to check for |
|
67477
966b87f2395c
Merged revisions 87873 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67365
diff
changeset
|
51 # header injection attack. |
|
966b87f2395c
Merged revisions 87873 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67365
diff
changeset
|
52 _embeded_header = re.compile(r'\n[^ \t]+:') |
|
966b87f2395c
Merged revisions 87873 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67365
diff
changeset
|
53 |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
54 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
55 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
56 # Helpers |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
57 _max_append = email.quoprimime._max_append |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
58 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
59 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
60 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
61 def decode_header(header): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
62 """Decode a message header value without converting charset. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
63 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
64 Returns a list of (string, charset) pairs containing each of the decoded |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
65 parts of the header. Charset is None for non-encoded parts of the header, |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
66 otherwise a lower-case string containing the name of the character set |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
67 specified in the encoded string. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
68 |
|
68928
b21fdfa0019c
#11584: Since __getitem__ returns headers, make decode_header handle them.
R David Murray <rdmurray@bitdance.com>
parents:
68626
diff
changeset
|
69 header may be a string that may or may not contain RFC2047 encoded words, |
|
b21fdfa0019c
#11584: Since __getitem__ returns headers, make decode_header handle them.
R David Murray <rdmurray@bitdance.com>
parents:
68626
diff
changeset
|
70 or it may be a Header object. |
|
b21fdfa0019c
#11584: Since __getitem__ returns headers, make decode_header handle them.
R David Murray <rdmurray@bitdance.com>
parents:
68626
diff
changeset
|
71 |
|
55226
57e9f2d367a8
Merged revisions 73952 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents:
43145
diff
changeset
|
72 An email.errors.HeaderParseError may be raised when certain decoding error |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
73 occurs (e.g. a base64 decoding exception). |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
74 """ |
|
70860
d62e5682a8ac
#11584: make decode_header handle Header objects correctly
R David Murray <rdmurray@bitdance.com>
parents:
69421
diff
changeset
|
75 # If it is a Header object, we can just return the encoded chunks. |
|
68928
b21fdfa0019c
#11584: Since __getitem__ returns headers, make decode_header handle them.
R David Murray <rdmurray@bitdance.com>
parents:
68626
diff
changeset
|
76 if hasattr(header, '_chunks'): |
|
70860
d62e5682a8ac
#11584: make decode_header handle Header objects correctly
R David Murray <rdmurray@bitdance.com>
parents:
69421
diff
changeset
|
77 return [(_charset._encode(string, str(charset)), str(charset)) |
|
d62e5682a8ac
#11584: make decode_header handle Header objects correctly
R David Murray <rdmurray@bitdance.com>
parents:
69421
diff
changeset
|
78 for string, charset in header._chunks] |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
79 # If no encoding, just return the header with no charset. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
80 if not ecre.search(header): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
81 return [(header, None)] |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
82 # First step is to parse all the encoded parts into triplets of the form |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
83 # (encoded_string, encoding, charset). For unencoded strings, the last |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
84 # two parts will be None. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
85 words = [] |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
86 for line in header.splitlines(): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
87 parts = ecre.split(line) |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
88 first = True |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
89 while parts: |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
90 unencoded = parts.pop(0) |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
91 if first: |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
92 unencoded = unencoded.lstrip() |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
93 first = False |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
94 if unencoded: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
95 words.append((unencoded, None, None)) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
96 if parts: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
97 charset = parts.pop(0).lower() |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
98 encoding = parts.pop(0).lower() |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
99 encoded = parts.pop(0) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
100 words.append((encoded, encoding, charset)) |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
101 # Now loop over words and remove words that consist of whitespace |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
102 # between two encoded strings. |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
103 import sys |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
104 droplist = [] |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
105 for n, w in enumerate(words): |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
106 if n>1 and w[1] and words[n-2][1] and words[n-1][0].isspace(): |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
107 droplist.append(n-1) |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
108 for d in reversed(droplist): |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
109 del words[d] |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
110 |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
111 # The next step is to decode each encoded word by applying the reverse |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
112 # base64 or quopri transformation. decoded_words is now a list of the |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
113 # form (decoded_word, charset). |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
114 decoded_words = [] |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
115 for encoded_string, encoding, charset in words: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
116 if encoding is None: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
117 # This is an unencoded word. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
118 decoded_words.append((encoded_string, charset)) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
119 elif encoding == 'q': |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
120 word = email.quoprimime.header_decode(encoded_string) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
121 decoded_words.append((word, charset)) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
122 elif encoding == 'b': |
|
63708
21a9c940110d
Merged revisions 83690 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
43145
diff
changeset
|
123 paderr = len(encoded_string) % 4 # Postel's law: add missing padding |
|
21a9c940110d
Merged revisions 83690 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
43145
diff
changeset
|
124 if paderr: |
|
21a9c940110d
Merged revisions 83690 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
43145
diff
changeset
|
125 encoded_string += '==='[:4 - paderr] |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
126 try: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
127 word = email.base64mime.decode(encoded_string) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
128 except binascii.Error: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
129 raise HeaderParseError('Base64 decoding error') |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
130 else: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
131 decoded_words.append((word, charset)) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
132 else: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
133 raise AssertionError('Unexpected encoding: ' + encoding) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
134 # Now convert all words to bytes and collapse consecutive runs of |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
135 # similarly encoded words. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
136 collapsed = [] |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
137 last_word = last_charset = None |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
138 for word, charset in decoded_words: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
139 if isinstance(word, str): |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
140 word = bytes(word, 'raw-unicode-escape') |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
141 if last_word is None: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
142 last_word = word |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
143 last_charset = charset |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
144 elif charset != last_charset: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
145 collapsed.append((last_word, last_charset)) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
146 last_word = word |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
147 last_charset = charset |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
148 elif last_charset is None: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
149 last_word += BSPACE + word |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
150 else: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
151 last_word += word |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
152 collapsed.append((last_word, last_charset)) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
153 return collapsed |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
154 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
155 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
156 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
157 def make_header(decoded_seq, maxlinelen=None, header_name=None, |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
158 continuation_ws=' '): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
159 """Create a Header from a sequence of pairs as returned by decode_header() |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
160 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
161 decode_header() takes a header value string and returns a sequence of |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
162 pairs of the format (decoded_string, charset) where charset is the string |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
163 name of the character set. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
164 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
165 This function takes one of those sequence of pairs and returns a Header |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
166 instance. Optional maxlinelen, header_name, and continuation_ws are as in |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
167 the Header constructor. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
168 """ |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
169 h = Header(maxlinelen=maxlinelen, header_name=header_name, |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
170 continuation_ws=continuation_ws) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
171 for s, charset in decoded_seq: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
172 # None means us-ascii but we can simply pass it on to h.append() |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
173 if charset is not None and not isinstance(charset, Charset): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
174 charset = Charset(charset) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
175 h.append(s, charset) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
176 return h |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
177 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
178 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
179 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
180 class Header: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
181 def __init__(self, s=None, charset=None, |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
182 maxlinelen=None, header_name=None, |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
183 continuation_ws=' ', errors='strict'): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
184 """Create a MIME-compliant header that can contain many character sets. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
185 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
186 Optional s is the initial header value. If None, the initial header |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
187 value is not set. You can later append to the header with .append() |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
188 method calls. s may be a byte string or a Unicode string, but see the |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
189 .append() documentation for semantics. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
190 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
191 Optional charset serves two purposes: it has the same meaning as the |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
192 charset argument to the .append() method. It also sets the default |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
193 character set for all subsequent .append() calls that omit the charset |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
194 argument. If charset is not provided in the constructor, the us-ascii |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
195 charset is used both as s's initial charset and as the default for |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
196 subsequent .append() calls. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
197 |
|
67214
2e592a4e68ab
Merged revisions 87567 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
63708
diff
changeset
|
198 The maximum line length can be specified explicitly via maxlinelen. For |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
199 splitting the first line to a shorter value (to account for the field |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
200 header which isn't included in s, e.g. `Subject') pass in the name of |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
201 the field in header_name. The default maxlinelen is 78 as recommended |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
202 by RFC 2822. |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
203 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
204 continuation_ws must be RFC 2822 compliant folding whitespace (usually |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
205 either a space or a hard tab) which will be prepended to continuation |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
206 lines. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
207 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
208 errors is passed through to the .append() call. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
209 """ |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
210 if charset is None: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
211 charset = USASCII |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
212 elif not isinstance(charset, Charset): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
213 charset = Charset(charset) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
214 self._charset = charset |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
215 self._continuation_ws = continuation_ws |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
216 self._chunks = [] |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
217 if s is not None: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
218 self.append(s, charset, errors) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
219 if maxlinelen is None: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
220 maxlinelen = MAXLINELEN |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
221 self._maxlinelen = maxlinelen |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
222 if header_name is None: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
223 self._headerlen = 0 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
224 else: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
225 # Take the separating colon and space into account. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
226 self._headerlen = len(header_name) + 2 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
227 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
228 def __str__(self): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
229 """Return the string value of the header.""" |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
230 self._normalize() |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
231 uchunks = [] |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
232 lastcs = None |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
233 lastspace = None |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
234 for string, charset in self._chunks: |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
235 # We must preserve spaces between encoded and non-encoded word |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
236 # boundaries, which means for us we need to add a space when we go |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
237 # from a charset to None/us-ascii, or from None/us-ascii to a |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
238 # charset. Only do this for the second and subsequent chunks. |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
239 # Don't add a space if the None/us-ascii string already has |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
240 # a space (trailing or leading depending on transition) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
241 nextcs = charset |
|
67447
cad1811d9e13
#10686: recode non-ASCII headers to 'unknown-8bit' instead of ?s.
R. David Murray <rdmurray@bitdance.com>
parents:
67446
diff
changeset
|
242 if nextcs == _charset.UNKNOWN8BIT: |
|
cad1811d9e13
#10686: recode non-ASCII headers to 'unknown-8bit' instead of ?s.
R. David Murray <rdmurray@bitdance.com>
parents:
67446
diff
changeset
|
243 original_bytes = string.encode('ascii', 'surrogateescape') |
|
cad1811d9e13
#10686: recode non-ASCII headers to 'unknown-8bit' instead of ?s.
R. David Murray <rdmurray@bitdance.com>
parents:
67446
diff
changeset
|
244 string = original_bytes.decode('ascii', 'replace') |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
245 if uchunks: |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
246 hasspace = string and self._nonctext(string[0]) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
247 if lastcs not in (None, 'us-ascii'): |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
248 if nextcs in (None, 'us-ascii') and not hasspace: |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
249 uchunks.append(SPACE) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
250 nextcs = None |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
251 elif nextcs not in (None, 'us-ascii') and not lastspace: |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
252 uchunks.append(SPACE) |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
253 lastspace = string and self._nonctext(string[-1]) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
254 lastcs = nextcs |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
255 uchunks.append(string) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
256 return EMPTYSTRING.join(uchunks) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
257 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
258 # Rich comparison operators for equality only. BAW: does it make sense to |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
259 # have or explicitly disable <, <=, >, >= operators? |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
260 def __eq__(self, other): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
261 # other may be a Header or a string. Both are fine so coerce |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
262 # ourselves to a unicode (of the unencoded header value), swap the |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
263 # args and do another comparison. |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
264 return other == str(self) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
265 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
266 def __ne__(self, other): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
267 return not self == other |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
268 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
269 def append(self, s, charset=None, errors='strict'): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
270 """Append a string to the MIME header. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
271 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
272 Optional charset, if given, should be a Charset instance or the name |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
273 of a character set (which will be converted to a Charset instance). A |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
274 value of None (the default) means that the charset given in the |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
275 constructor is used. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
276 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
277 s may be a byte string or a Unicode string. If it is a byte string |
|
67214
2e592a4e68ab
Merged revisions 87567 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
63708
diff
changeset
|
278 (i.e. isinstance(s, str) is false), then charset is the encoding of |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
279 that byte string, and a UnicodeError will be raised if the string |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
280 cannot be decoded with that charset. If s is a Unicode string, then |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
281 charset is a hint specifying the character set of the characters in |
|
67365
0effb175c981
Merged revisions 87750 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67214
diff
changeset
|
282 the string. In either case, when producing an RFC 2822 compliant |
|
0effb175c981
Merged revisions 87750 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67214
diff
changeset
|
283 header using RFC 2047 rules, the string will be encoded using the |
|
0effb175c981
Merged revisions 87750 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67214
diff
changeset
|
284 output codec of the charset. If the string cannot be encoded to the |
|
0effb175c981
Merged revisions 87750 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67214
diff
changeset
|
285 output codec, a UnicodeError will be raised. |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
286 |
|
67365
0effb175c981
Merged revisions 87750 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67214
diff
changeset
|
287 Optional `errors' is passed as the errors argument to the decode |
|
0effb175c981
Merged revisions 87750 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67214
diff
changeset
|
288 call if s is a byte string. |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
289 """ |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
290 if charset is None: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
291 charset = self._charset |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
292 elif not isinstance(charset, Charset): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
293 charset = Charset(charset) |
|
67365
0effb175c981
Merged revisions 87750 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67214
diff
changeset
|
294 if not isinstance(s, str): |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
295 input_charset = charset.input_codec or 'us-ascii' |
|
70862
3875ccea6367
#11584: make Header and make_header handle binary unknown-8bit input
R David Murray <rdmurray@bitdance.com>
parents:
70860
diff
changeset
|
296 if input_charset == _charset.UNKNOWN8BIT: |
|
3875ccea6367
#11584: make Header and make_header handle binary unknown-8bit input
R David Murray <rdmurray@bitdance.com>
parents:
70860
diff
changeset
|
297 s = s.decode('us-ascii', 'surrogateescape') |
|
3875ccea6367
#11584: make Header and make_header handle binary unknown-8bit input
R David Murray <rdmurray@bitdance.com>
parents:
70860
diff
changeset
|
298 else: |
|
3875ccea6367
#11584: make Header and make_header handle binary unknown-8bit input
R David Murray <rdmurray@bitdance.com>
parents:
70860
diff
changeset
|
299 s = s.decode(input_charset, errors) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
300 # Ensure that the bytes we're storing can be decoded to the output |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
301 # character set, otherwise an early error is thrown. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
302 output_charset = charset.output_codec or 'us-ascii' |
|
67447
cad1811d9e13
#10686: recode non-ASCII headers to 'unknown-8bit' instead of ?s.
R. David Murray <rdmurray@bitdance.com>
parents:
67446
diff
changeset
|
303 if output_charset != _charset.UNKNOWN8BIT: |
|
75621
fd4b4650856f
#14291: if a header has non-ascii unicode, default to CTE using utf-8
R David Murray <rdmurray@bitdance.com>
parents:
70862
diff
changeset
|
304 try: |
|
fd4b4650856f
#14291: if a header has non-ascii unicode, default to CTE using utf-8
R David Murray <rdmurray@bitdance.com>
parents:
70862
diff
changeset
|
305 s.encode(output_charset, errors) |
|
fd4b4650856f
#14291: if a header has non-ascii unicode, default to CTE using utf-8
R David Murray <rdmurray@bitdance.com>
parents:
70862
diff
changeset
|
306 except UnicodeEncodeError: |
|
fd4b4650856f
#14291: if a header has non-ascii unicode, default to CTE using utf-8
R David Murray <rdmurray@bitdance.com>
parents:
70862
diff
changeset
|
307 if output_charset!='us-ascii': |
|
fd4b4650856f
#14291: if a header has non-ascii unicode, default to CTE using utf-8
R David Murray <rdmurray@bitdance.com>
parents:
70862
diff
changeset
|
308 raise |
|
fd4b4650856f
#14291: if a header has non-ascii unicode, default to CTE using utf-8
R David Murray <rdmurray@bitdance.com>
parents:
70862
diff
changeset
|
309 charset = UTF8 |
|
67365
0effb175c981
Merged revisions 87750 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67214
diff
changeset
|
310 self._chunks.append((s, charset)) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
311 |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
312 def _nonctext(self, s): |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
313 """True if string s is not a ctext character of RFC822. |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
314 """ |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
315 return s.isspace() or s in ('(', ')', '\\') |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
316 |
|
65611
ebf6741a8d6e
#1349106: add linesep argument to generator.flatten and header.encode.
R. David Murray <rdmurray@bitdance.com>
parents:
63705
diff
changeset
|
317 def encode(self, splitchars=';, \t', maxlinelen=None, linesep='\n'): |
|
68471
f6cab3819160
Harmonize linesep docstrings, and fix the quoting of \r\n
R David Murray <rdmurray@bitdance.com>
parents:
68257
diff
changeset
|
318 r"""Encode a message header into an RFC-compliant format. |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
319 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
320 There are many issues involved in converting a given string for use in |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
321 an email header. Only certain character sets are readable in most |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
322 email clients, and as header strings can only contain a subset of |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
323 7-bit ASCII, care must be taken to properly convert and encode (with |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
324 Base64 or quoted-printable) header strings. In addition, there is a |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
325 75-character length limit on any given encoded header field, so |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
326 line-wrapping must be performed, even with double-byte character sets. |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
327 |
|
69323
bbed01a7d0d1
Fix typo in docstring.
Ezio Melotti <ezio.melotti@gmail.com>
parents:
69272
diff
changeset
|
328 Optional maxlinelen specifies the maximum length of each generated |
|
69272
f9bd0add9732
Add maxlinelen to docstring, delete obsolete wording
R David Murray <rdmurray@bitdance.com>
parents:
69201
diff
changeset
|
329 line, exclusive of the linesep string. Individual lines may be longer |
|
f9bd0add9732
Add maxlinelen to docstring, delete obsolete wording
R David Murray <rdmurray@bitdance.com>
parents:
69201
diff
changeset
|
330 than maxlinelen if a folding point cannot be found. The first line |
|
f9bd0add9732
Add maxlinelen to docstring, delete obsolete wording
R David Murray <rdmurray@bitdance.com>
parents:
69201
diff
changeset
|
331 will be shorter by the length of the header name plus ": " if a header |
|
f9bd0add9732
Add maxlinelen to docstring, delete obsolete wording
R David Murray <rdmurray@bitdance.com>
parents:
69201
diff
changeset
|
332 name was specified at Header construction time. The default value for |
|
f9bd0add9732
Add maxlinelen to docstring, delete obsolete wording
R David Murray <rdmurray@bitdance.com>
parents:
69201
diff
changeset
|
333 maxlinelen is determined at header construction time. |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
334 |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
335 Optional splitchars is a string containing characters which should be |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
336 given extra weight by the splitting algorithm during normal header |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
337 wrapping. This is in very rough support of RFC 2822's `higher level |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
338 syntactic breaks': split points preceded by a splitchar are preferred |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
339 during line splitting, with the characters preferred in the order in |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
340 which they appear in the string. Space and tab may be included in the |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
341 string to indicate whether preference should be given to one over the |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
342 other as a split point when other split chars do not appear in the line |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
343 being split. Splitchars does not affect RFC 2047 encoded lines. |
|
65611
ebf6741a8d6e
#1349106: add linesep argument to generator.flatten and header.encode.
R. David Murray <rdmurray@bitdance.com>
parents:
63705
diff
changeset
|
344 |
|
ebf6741a8d6e
#1349106: add linesep argument to generator.flatten and header.encode.
R. David Murray <rdmurray@bitdance.com>
parents:
63705
diff
changeset
|
345 Optional linesep is a string to be used to separate the lines of |
|
ebf6741a8d6e
#1349106: add linesep argument to generator.flatten and header.encode.
R. David Murray <rdmurray@bitdance.com>
parents:
63705
diff
changeset
|
346 the value. The default value is the most useful for typical |
|
ebf6741a8d6e
#1349106: add linesep argument to generator.flatten and header.encode.
R. David Murray <rdmurray@bitdance.com>
parents:
63705
diff
changeset
|
347 Python applications, but it can be set to \r\n to produce RFC-compliant |
|
ebf6741a8d6e
#1349106: add linesep argument to generator.flatten and header.encode.
R. David Murray <rdmurray@bitdance.com>
parents:
63705
diff
changeset
|
348 line separators when needed. |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
349 """ |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
350 self._normalize() |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
351 if maxlinelen is None: |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
352 maxlinelen = self._maxlinelen |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
353 # A maxlinelen of 0 means don't wrap. For all practical purposes, |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
354 # choosing a huge number here accomplishes that and makes the |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
355 # _ValueFormatter algorithm much simpler. |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
356 if maxlinelen == 0: |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
357 maxlinelen = 1000000 |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
358 formatter = _ValueFormatter(self._headerlen, maxlinelen, |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
359 self._continuation_ws, splitchars) |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
360 lastcs = None |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
361 hasspace = lastspace = None |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
362 for string, charset in self._chunks: |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
363 if hasspace is not None: |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
364 hasspace = string and self._nonctext(string[0]) |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
365 import sys |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
366 if lastcs not in (None, 'us-ascii'): |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
367 if not hasspace or charset not in (None, 'us-ascii'): |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
368 formatter.add_transition() |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
369 elif charset not in (None, 'us-ascii') and not lastspace: |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
370 formatter.add_transition() |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
371 lastspace = string and self._nonctext(string[-1]) |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
372 lastcs = charset |
|
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
373 hasspace = False |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
374 lines = string.splitlines() |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
375 if lines: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
376 formatter.feed('', lines[0], charset) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
377 else: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
378 formatter.feed('', '', charset) |
|
67917
8084c668b637
Merged revisions 87136,87221,87256,87337-87338,87571,87839,88164 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67477
diff
changeset
|
379 for line in lines[1:]: |
|
8084c668b637
Merged revisions 87136,87221,87256,87337-87338,87571,87839,88164 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67477
diff
changeset
|
380 formatter.newline() |
|
8084c668b637
Merged revisions 87136,87221,87256,87337-87338,87571,87839,88164 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67477
diff
changeset
|
381 if charset.header_encoding is not None: |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
382 formatter.feed(self._continuation_ws, ' ' + line.lstrip(), |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
383 charset) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
384 else: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
385 sline = line.lstrip() |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
386 fws = line[:len(line)-len(sline)] |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
387 formatter.feed(fws, sline, charset) |
|
67917
8084c668b637
Merged revisions 87136,87221,87256,87337-87338,87571,87839,88164 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67477
diff
changeset
|
388 if len(lines) > 1: |
|
8084c668b637
Merged revisions 87136,87221,87256,87337-87338,87571,87839,88164 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67477
diff
changeset
|
389 formatter.newline() |
|
77308
8c03fe231877
#1079: Fix parsing of encoded words.
R David Murray <rdmurray@bitdance.com>
parents:
75621
diff
changeset
|
390 if self._chunks: |
|
43113
7ec04cb262d2
More email package fixes.
Barry Warsaw <barry@python.org>
parents:
43045
diff
changeset
|
391 formatter.add_transition() |
|
67476
8bbff1c24a31
#5871: protect against header injection attacks.
R. David Murray <rdmurray@bitdance.com>
parents:
67447
diff
changeset
|
392 value = formatter._str(linesep) |
|
67477
966b87f2395c
Merged revisions 87873 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67365
diff
changeset
|
393 if _embeded_header.search(value): |
|
966b87f2395c
Merged revisions 87873 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67365
diff
changeset
|
394 raise HeaderParseError("header value appears to contain " |
|
966b87f2395c
Merged revisions 87873 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67365
diff
changeset
|
395 "an embedded header: {!r}".format(value)) |
|
966b87f2395c
Merged revisions 87873 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents:
67365
diff
changeset
|
396 return value |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
397 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
398 def _normalize(self): |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
399 # Step 1: Normalize the chunks so that all runs of identical charsets |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
400 # get collapsed into a single unicode string. |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
401 chunks = [] |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
402 last_charset = None |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
403 last_chunk = [] |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
404 for string, charset in self._chunks: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
405 if charset == last_charset: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
406 last_chunk.append(string) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
407 else: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
408 if last_charset is not None: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
409 chunks.append((SPACE.join(last_chunk), last_charset)) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
410 last_chunk = [string] |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
411 last_charset = charset |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
412 if last_chunk: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
413 chunks.append((SPACE.join(last_chunk), last_charset)) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
414 self._chunks = chunks |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
415 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
416 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
417 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
418 class _ValueFormatter: |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
419 def __init__(self, headerlen, maxlen, continuation_ws, splitchars): |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
420 self._maxlen = maxlen |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
421 self._continuation_ws = continuation_ws |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
422 self._continuation_ws_len = len(continuation_ws) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
423 self._splitchars = splitchars |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
424 self._lines = [] |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
425 self._current_line = _Accumulator(headerlen) |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
426 |
|
65611
ebf6741a8d6e
#1349106: add linesep argument to generator.flatten and header.encode.
R. David Murray <rdmurray@bitdance.com>
parents:
63705
diff
changeset
|
427 def _str(self, linesep): |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
428 self.newline() |
|
65611
ebf6741a8d6e
#1349106: add linesep argument to generator.flatten and header.encode.
R. David Murray <rdmurray@bitdance.com>
parents:
63705
diff
changeset
|
429 return linesep.join(self._lines) |
|
ebf6741a8d6e
#1349106: add linesep argument to generator.flatten and header.encode.
R. David Murray <rdmurray@bitdance.com>
parents:
63705
diff
changeset
|
430 |
|
ebf6741a8d6e
#1349106: add linesep argument to generator.flatten and header.encode.
R. David Murray <rdmurray@bitdance.com>
parents:
63705
diff
changeset
|
431 def __str__(self): |
|
ebf6741a8d6e
#1349106: add linesep argument to generator.flatten and header.encode.
R. David Murray <rdmurray@bitdance.com>
parents:
63705
diff
changeset
|
432 return self._str(NL) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
433 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
434 def newline(self): |
|
43113
7ec04cb262d2
More email package fixes.
Barry Warsaw <barry@python.org>
parents:
43045
diff
changeset
|
435 end_of_line = self._current_line.pop() |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
436 if end_of_line != (' ', ''): |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
437 self._current_line.push(*end_of_line) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
438 if len(self._current_line) > 0: |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
439 if self._current_line.is_onlyws(): |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
440 self._lines[-1] += str(self._current_line) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
441 else: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
442 self._lines.append(str(self._current_line)) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
443 self._current_line.reset() |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
444 |
|
43113
7ec04cb262d2
More email package fixes.
Barry Warsaw <barry@python.org>
parents:
43045
diff
changeset
|
445 def add_transition(self): |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
446 self._current_line.push(' ', '') |
|
43113
7ec04cb262d2
More email package fixes.
Barry Warsaw <barry@python.org>
parents:
43045
diff
changeset
|
447 |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
448 def feed(self, fws, string, charset): |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
449 # If the charset has no header encoding (i.e. it is an ASCII encoding) |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
450 # then we must split the header at the "highest level syntactic break" |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
451 # possible. Note that we don't have a lot of smarts about field |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
452 # syntax; we just try to break on semi-colons, then commas, then |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
453 # whitespace. Eventually, this should be pluggable. |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
454 if charset.header_encoding is None: |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
455 self._ascii_split(fws, string, self._splitchars) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
456 return |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
457 # Otherwise, we're doing either a Base64 or a quoted-printable |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
458 # encoding which means we don't need to split the line on syntactic |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
459 # breaks. We can basically just find enough characters to fit on the |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
460 # current line, minus the RFC 2047 chrome. What makes this trickier |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
461 # though is that we have to split at octet boundaries, not character |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
462 # boundaries but it's only safe to split at character boundaries so at |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
463 # best we can only get close. |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
464 encoded_lines = charset.header_encode_lines(string, self._maxlengths()) |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
465 # The first element extends the current line, but if it's None then |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
466 # nothing more fit on the current line so start a new line. |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
467 try: |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
468 first_line = encoded_lines.pop(0) |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
469 except IndexError: |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
470 # There are no encoded lines, so we're done. |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
471 return |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
472 if first_line is not None: |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
473 self._append_chunk(fws, first_line) |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
474 try: |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
475 last_line = encoded_lines.pop() |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
476 except IndexError: |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
477 # There was only one line. |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
478 return |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
479 self.newline() |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
480 self._current_line.push(self._continuation_ws, last_line) |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
481 # Everything else are full lines in themselves. |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
482 for line in encoded_lines: |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
483 self._lines.append(self._continuation_ws + line) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
484 |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
485 def _maxlengths(self): |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
486 # The first line's length. |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
487 yield self._maxlen - len(self._current_line) |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
488 while True: |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
489 yield self._maxlen - self._continuation_ws_len |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
490 |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
491 def _ascii_split(self, fws, string, splitchars): |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
492 # The RFC 2822 header folding algorithm is simple in principle but |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
493 # complex in practice. Lines may be folded any place where "folding |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
494 # white space" appears by inserting a linesep character in front of the |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
495 # FWS. The complication is that not all spaces or tabs qualify as FWS, |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
496 # and we are also supposed to prefer to break at "higher level |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
497 # syntactic breaks". We can't do either of these without intimate |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
498 # knowledge of the structure of structured headers, which we don't have |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
499 # here. So the best we can do here is prefer to break at the specified |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
500 # splitchars, and hope that we don't choose any spaces or tabs that |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
501 # aren't legal FWS. (This is at least better than the old algorithm, |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
502 # where we would sometimes *introduce* FWS after a splitchar, or the |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
503 # algorithm before that, where we would turn all white space runs into |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
504 # single spaces or tabs.) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
505 parts = re.split("(["+FWS+"]+)", fws+string) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
506 if parts[0]: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
507 parts[:0] = [''] |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
508 else: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
509 parts.pop(0) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
510 for fws, part in zip(*[iter(parts)]*2): |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
511 self._append_chunk(fws, part) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
512 |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
513 def _append_chunk(self, fws, string): |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
514 self._current_line.push(fws, string) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
515 if len(self._current_line) > self._maxlen: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
516 # Find the best split point, working backward from the end. |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
517 # There might be none, on a long first line. |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
518 for ch in self._splitchars: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
519 for i in range(self._current_line.part_count()-1, 0, -1): |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
520 if ch.isspace(): |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
521 fws = self._current_line[i][0] |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
522 if fws and fws[0]==ch: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
523 break |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
524 prevpart = self._current_line[i-1][1] |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
525 if prevpart and prevpart[-1]==ch: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
526 break |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
527 else: |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
528 continue |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
529 break |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
530 else: |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
531 fws, part = self._current_line.pop() |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
532 if self._current_line._initial_size > 0: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
533 # There will be a header, so leave it on a line by itself. |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
534 self.newline() |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
535 if not fws: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
536 # We don't use continuation_ws here because the whitespace |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
537 # after a header should always be a space. |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
538 fws = ' ' |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
539 self._current_line.push(fws, part) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
540 return |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
541 remainder = self._current_line.pop_from(i) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
542 self._lines.append(str(self._current_line)) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
543 self._current_line.reset(remainder) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
544 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
545 |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
546 class _Accumulator(list): |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
547 |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
548 def __init__(self, initial_size=0): |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
549 self._initial_size = initial_size |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
550 super().__init__() |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
551 |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
552 def push(self, fws, string): |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
553 self.append((fws, string)) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
554 |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
555 def pop_from(self, i=0): |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
556 popped = self[i:] |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
557 self[i:] = [] |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
558 return popped |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
559 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
560 def pop(self): |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
561 if self.part_count()==0: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
562 return ('', '') |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
563 return super().pop() |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
564 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
565 def __len__(self): |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
566 return sum((len(fws)+len(part) for fws, part in self), |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
567 self._initial_size) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
568 |
|
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
569 def __str__(self): |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
570 return EMPTYSTRING.join((EMPTYSTRING.join((fws, part)) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
571 for fws, part in self)) |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
572 |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
573 def reset(self, startval=None): |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
574 if startval is None: |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
575 startval = [] |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
576 self[:] = startval |
|
43019
d5f3c2f416f2
Copying the email package back, despite its failings.
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
577 self._initial_size = 0 |
|
43024
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
578 |
|
1321ba0b670f
Oops. I copied a slightly older version of the email package from the sandbox.
Guido van Rossum <guido@python.org>
parents:
43019
diff
changeset
|
579 def is_onlyws(self): |
|
69421
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
580 return self._initial_size==0 and (not self or str(self).isspace()) |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
581 |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
582 def part_count(self): |
|
51a551acb60d
#11492: rewrite header folding algorithm. Less code, more passing tests.
R David Murray <rdmurray@bitdance.com>
parents:
69324
diff
changeset
|
583 return super().__len__() |
