Skip to content

Commit 28ace85

Browse files
author
Ralf Schlatterbeck
committed
fix problem with bounce-message if incoming mail has insufficient privilege...
...e.g., user not existing (issue 2550534) Added a regression test for this issue that reproduces the traceback reported in issue 2550534 I'm using a slightly modified variant of the original patch that avoids repeated string-concatenation (which could degenerate to quadratic runtime behaviour for large number of email headers).
1 parent 6475b05 commit 28ace85

File tree

3 files changed

+85
-13
lines changed

3 files changed

+85
-13
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Fixes:
1010
- fix problems with french and german locale files (issue 2550546)
1111
- Run each message of the mail-gateway in a separate transaction,
1212
see http://thread.gmane.org/gmane.comp.bug-tracking.roundup.user/9500
13+
- fix problem with bounce-message if incoming mail has insufficient
14+
privilege, e.g., user not existing (issue 2550534)
1315

1416

1517
2009-03-18 1.4.8 (r4209)

roundup/mailer.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -140,24 +140,25 @@ def bounce_message(self, bounced_message, to, error,
140140
elif error_messages_to == "both":
141141
to.append(dispatcher_email)
142142

143-
message = self.get_standard_message(to, subject)
143+
message = self.get_standard_message(to, subject, multipart=True)
144144

145145
# add the error text
146-
part = MIMEText(error)
146+
part = MIMEText('\n'.join(error))
147147
message.attach(part)
148148

149149
# attach the original message to the returned message
150+
body = []
151+
for header in bounced_message.headers:
152+
body.append(header)
150153
try:
151154
bounced_message.rewindbody()
152-
except IOError, message:
153-
body.write("*** couldn't include message body: %s ***"
154-
% bounced_message)
155+
except IOError, errmessage:
156+
body.append("*** couldn't include message body: %s ***" %
157+
errmessage)
155158
else:
156-
body.write(bounced_message.fp.read())
157-
part = MIMEText(bounced_message.fp.read())
158-
part['Content-Disposition'] = 'attachment'
159-
for header in bounced_message.headers:
160-
part.write(header)
159+
body.append('\n')
160+
body.append(bounced_message.fp.read())
161+
part = MIMEText(''.join(body))
161162
message.attach(part)
162163

163164
# send

test/test_mailgw.py

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def compareMessages(self, new, old):
5151
if not new == old:
5252
res = []
5353

54+
replace = {}
5455
for key in new.keys():
5556
if key.startswith('from '):
5657
# skip the unix from line
@@ -60,11 +61,18 @@ def compareMessages(self, new, old):
6061
if new[key] != __version__:
6162
res.append(' %s: %r != %r' % (key, __version__,
6263
new[key]))
64+
elif key.lower() == 'content-type' and 'boundary=' in new[key]:
65+
# handle mime messages
66+
newmime = new[key].split('=',1)[-1].strip('"')
67+
oldmime = old.get(key, '').split('=',1)[-1].strip('"')
68+
replace ['--' + newmime] = '--' + oldmime
69+
replace ['--' + newmime + '--'] = '--' + oldmime + '--'
6370
elif new.get(key, '') != old.get(key, ''):
6471
res.append(' %s: %r != %r' % (key, old.get(key, ''),
6572
new.get(key, '')))
6673

67-
body_diff = self.compareStrings(new.fp.read(), old.fp.read())
74+
body_diff = self.compareStrings(new.fp.read(), old.fp.read(),
75+
replace=replace)
6876
if body_diff:
6977
res.append('')
7078
res.extend(body_diff)
@@ -73,13 +81,14 @@ def compareMessages(self, new, old):
7381
res.insert(0, 'Generated message not correct (diff follows):')
7482
raise AssertionError, '\n'.join(res)
7583

76-
def compareStrings(self, s2, s1):
84+
def compareStrings(self, s2, s1, replace={}):
7785
'''Note the reversal of s2 and s1 - difflib.SequenceMatcher wants
7886
the first to be the "original" but in the calls in this file,
7987
the second arg is the original. Ho hum.
88+
Do replacements over the replace dict -- used for mime boundary
8089
'''
8190
l1 = s1.strip().split('\n')
82-
l2 = s2.strip().split('\n')
91+
l2 = [replace.get(i,i) for i in s2.strip().split('\n')]
8392
if l1 == l2:
8493
return
8594
s = difflib.SequenceMatcher(None, l1, l2)
@@ -1105,6 +1114,66 @@ def hook (db, **kw):
11051114
name = self.db.user.get(new, 'realname')
11061115
self.assertEquals(name, 'H€llo')
11071116

1117+
def testUnknownUser(self):
1118+
l = set(self.db.user.list())
1119+
message = '''Content-Type: text/plain;
1120+
charset="iso-8859-1"
1121+
From: Nonexisting User <[email protected]>
1122+
1123+
Message-Id: <dummy_test_message_id>
1124+
Subject: [issue] Testing nonexisting user...
1125+
1126+
This is a test submission of a new issue.
1127+
'''
1128+
self.db.close()
1129+
handler = self.instance.MailGW(self.instance)
1130+
# we want a bounce message:
1131+
handler.trapExceptions = 1
1132+
ret = handler.main(StringIO(message))
1133+
self.compareMessages(self._get_mail(),
1134+
'''FROM: Roundup issue tracker <[email protected]>
1135+
1136+
From nobody Tue Jul 14 12:04:11 2009
1137+
Content-Type: multipart/mixed; boundary="===============0639262320=="
1138+
MIME-Version: 1.0
1139+
Subject: Failed issue tracker submission
1140+
1141+
From: Roundup issue tracker <[email protected]>
1142+
Date: Tue, 14 Jul 2009 12:04:11 +0000
1143+
Precedence: bulk
1144+
X-Roundup-Name: Roundup issue tracker
1145+
X-Roundup-Loop: hello
1146+
X-Roundup-Version: 1.4.8
1147+
MIME-Version: 1.0
1148+
1149+
--===============0639262320==
1150+
Content-Type: text/plain; charset="us-ascii"
1151+
MIME-Version: 1.0
1152+
Content-Transfer-Encoding: 7bit
1153+
1154+
1155+
1156+
You are not a registered user.
1157+
1158+
Unknown address: [email protected]
1159+
1160+
--===============0639262320==
1161+
Content-Type: text/plain; charset="us-ascii"
1162+
MIME-Version: 1.0
1163+
Content-Transfer-Encoding: 7bit
1164+
1165+
Content-Type: text/plain;
1166+
charset="iso-8859-1"
1167+
From: Nonexisting User <[email protected]>
1168+
1169+
Message-Id: <dummy_test_message_id>
1170+
Subject: [issue] Testing nonexisting user...
1171+
1172+
This is a test submission of a new issue.
1173+
1174+
--===============0639262320==--
1175+
''')
1176+
11081177
def testEnc01(self):
11091178
self.doNewIssue()
11101179
self._handle_mail('''Content-Type: text/plain;

0 commit comments

Comments
 (0)