File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -29,7 +29,10 @@ def process(msg):
2929 return
3030 addrs = []
3131 found = False
32- for line in msg .get_payload (decode = True ).splitlines ():
32+ payload = msg .get_payload (decode = True )
33+ if isinstance (payload , bytes ):
34+ payload = payload .decode ('us-ascii' , errors = 'replace' )
35+ for line in payload .splitlines ():
3336 if scre .search (line ):
3437 found = True
3538 continue
Original file line number Diff line number Diff line change 1717
1818"""Recognizes simple heuristically delimited bounces."""
1919
20+ import io
2021import re
2122import email .iterators
2223
2324
25+ def _body_line_iterator (msg ):
26+ """Iterate body lines with Content-Transfer-Encoding properly decoded.
27+
28+ Python 3's body_line_iterator only yields str payloads; get_payload(
29+ decode=True) returns bytes (CTE-decoded). This helper bridges the gap so
30+ quoted-printable and base64 bodies are decoded before pattern matching.
31+ """
32+ for subpart in email .iterators .typed_subpart_iterator (msg ):
33+ payload = subpart .get_payload (decode = True )
34+ if not isinstance (payload , bytes ):
35+ continue
36+ charset = subpart .get_content_charset ('us-ascii' ) or 'us-ascii'
37+ try :
38+ text = payload .decode (charset , errors = 'replace' )
39+ except LookupError :
40+ text = payload .decode ('us-ascii' , errors = 'replace' )
41+ yield from io .StringIO (text )
42+
43+
2444
2545def _c (pattern ):
2646 return re .compile (pattern , re .IGNORECASE )
@@ -224,7 +244,7 @@ def process(msg, patterns=None):
224244 # we process the message multiple times anyway.
225245 for scre , ecre , acre in patterns :
226246 state = 0
227- for line in email . iterators . body_line_iterator (msg , decode = True ):
247+ for line in _body_line_iterator (msg ):
228248 if state == 0 :
229249 if scre .search (line ):
230250 state = 1
Original file line number Diff line number Diff line change 2121import email .iterators
2222
2323from Mailman .Bouncers .BouncerAPI import Stop
24- from Mailman .Bouncers .SimpleMatch import _c
24+ from Mailman .Bouncers .SimpleMatch import _c , _body_line_iterator
2525
2626
2727
@@ -75,7 +75,7 @@ def process(msg):
7575 addrs = {}
7676 for scre , ecre , acre in patterns :
7777 state = 0
78- for line in email . iterators . body_line_iterator (msg , decode = True ):
78+ for line in _body_line_iterator (msg ):
7979 if state == 0 :
8080 if scre .search (line ):
8181 state = 1
Original file line number Diff line number Diff line change 2626from email .header import decode_header
2727
2828from Mailman import Utils
29+ from Mailman .Bouncers .SimpleMatch import _body_line_iterator
2930from Mailman .Logging .Syslog import syslog
3031from Mailman .Handlers .CookHeaders import change_header
3132
@@ -97,7 +98,7 @@ def scanbody(msg, numlines=None):
9798 # the first numlines of body text.
9899 lines = []
99100 lineno = 0
100- reader = list (email . iterators . body_line_iterator (msg , decode = True ))
101+ reader = list (_body_line_iterator (msg ))
101102 while numlines is None or lineno < numlines :
102103 try :
103104 line = reader .pop (0 )
You can’t perform that action at this time.
0 commit comments