From f10605db754277a509f99ae35538cd066d0143e2 Mon Sep 17 00:00:00 2001
From: Mark Sapiro <mark@msapiro.net>
Date: Thu, 1 Mar 2018 09:26:02 -0800
Subject: Removed a Python 2.7 dependency introduced in 2.1.26.

---
 Mailman/Cgi/subscribe.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'Mailman')

diff --git a/Mailman/Cgi/subscribe.py b/Mailman/Cgi/subscribe.py
index 3977268c..aefce493 100755
--- a/Mailman/Cgi/subscribe.py
+++ b/Mailman/Cgi/subscribe.py
@@ -151,7 +151,7 @@ def process_form(mlist, doc, cgidata, lang):
             if not captcha_response['success']:
                 e_codes = COMMASPACE.join(captcha_response['error-codes'])
                 results.append(_('reCAPTCHA validation failed: %(e_codes)s'))
-        except urllib2.URLError as e:
+        except urllib2.URLError, e:
             e_reason = e.reason
             results.append(_('reCAPTCHA could not be validated: %(e_reason)s'))
 
-- 
cgit v1.2.3


From e61719889de7b570adb19af5e223c66f1e09e8bc Mon Sep 17 00:00:00 2001
From: Mark Sapiro <mark@msapiro.net>
Date: Thu, 8 Mar 2018 16:00:54 -0800
Subject: Bad values in topics no longer break the list.

---
 Mailman/MailList.py | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

(limited to 'Mailman')

diff --git a/Mailman/MailList.py b/Mailman/MailList.py
index d1dc17a4..619c3206 100755
--- a/Mailman/MailList.py
+++ b/Mailman/MailList.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2016 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -784,8 +784,16 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin,
             self.reply_to_address = ''
             self.reply_goes_to_list = 0
         # Legacy topics may have bad regular expressions in their patterns
+        # Also, someone may have broken topics with, e.g., config_list.
         goodtopics = []
-        for name, pattern, desc, emptyflag in self.topics:
+        for value in self.topics:
+            try:
+                name, pattern, desc, emptyflag = value
+            except ValueError:
+                # This value is not a 4-tuple. Just log and drop it.
+                syslog('error', 'Bad topic "%s" for list: %s',
+                       value, self.internal_name())
+                continue
             try:
                 orpattern = OR.join(pattern.splitlines())
                 re.compile(orpattern)
-- 
cgit v1.2.3


From 21eafd3e46083eded01f67ea828bc7b46ffb3f07 Mon Sep 17 00:00:00 2001
From: Mark Sapiro <mark@msapiro.net>
Date: Thu, 8 Mar 2018 17:33:07 -0800
Subject: Added a few more badword checks to Utils.suspiciousHTML(). Added
 validation of GUI updates to host_name.

---
 Mailman/Gui/General.py | 10 +++++++++-
 Mailman/Utils.py       | 31 +++++++++++++++++++++++++++----
 2 files changed, 36 insertions(+), 5 deletions(-)

(limited to 'Mailman')

diff --git a/Mailman/Gui/General.py b/Mailman/Gui/General.py
index 980e5f2b..dfde6309 100644
--- a/Mailman/Gui/General.py
+++ b/Mailman/Gui/General.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2014 by the Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -559,6 +559,14 @@ mlist.info.
                                           or not isinstance(val, IntType)):
             doc.addError(_("""<b>admin_member_chunksize</b> attribute not
             changed!  It must be an integer > 0."""))
+        elif property == 'host_name':
+            try:
+                Utils.ValidateEmail('user@' + val)
+            except Errors.EmailAddressError:
+                doc.addError(_("""<b>host_name</b> attribute not changed!
+                It must be a valid domain name."""))
+            else:
+                GUIBase._setValue(self, mlist, property, val, doc)
         else:
             GUIBase._setValue(self, mlist, property, val, doc)
 
diff --git a/Mailman/Utils.py b/Mailman/Utils.py
index 9dbd0b55..fd6ac796 100644
--- a/Mailman/Utils.py
+++ b/Mailman/Utils.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2017 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -1019,6 +1019,7 @@ _badwords = [
     '<meta',
     '<object',
     '<script',
+    '@keyframes',
     r'\bj(?:ava)?script\b',
     r'\bvbs(?:cript)?\b',
     r'\bdomactivate\b',
@@ -1035,12 +1036,14 @@ _badwords = [
     r'\bon(?:de)?activate\b',
     r'\bon(?:after|before)print\b',
     r'\bon(?:after|before)update\b',
+    r'\b(?:on)?animation(?:end|iteration|start)\b',
     r'\bonbefore(?:(?:de)?activate|copy|cut|editfocus|paste)\b',
     r'\bonbeforeunload\b',
     r'\bonbegin\b',
     r'\bonblur\b',
     r'\bonbounce\b',
     r'\bonbroadcast\b',
+    r'\boncanplay(?:through)?\b',
     r'\bon(?:cell)?change\b',
     r'\boncheckboxstatechange\b',
     r'\bon(?:dbl)?click\b',
@@ -1056,7 +1059,9 @@ _badwords = [
     r'\bondrag(?:drop|end|enter|exit|gesture|leave|over)?\b',
     r'\bondragstart\b',
     r'\bondrop\b',
-    r'\bonend\b',
+    r'\bondurationchange\b',
+    r'\bonemptied\b',
+    r'\bonend(?:ed)?\b',
     r'\bonerror(?:update)?\b',
     r'\bonfilterchange\b',
     r'\bonfinish\b',
@@ -1066,21 +1071,28 @@ _badwords = [
     r'\bonkey(?:up|down|press)\b',
     r'\bonlayoutcomplete\b',
     r'\bon(?:un)?load\b',
+    r'\bonloaded(?:meta)?data\b',
+    r'\bonloadstart\b',
     r'\bonlosecapture\b',
     r'\bonmedia(?:complete|error)\b',
+    r'\bonmessage\b',
     r'\bonmouse(?:down|enter|leave|move|out|over|up|wheel)\b',
     r'\bonmove(?:end|start)?\b',
     r'\bon(?:off|on)line\b',
+    r'\bonopen\b',
     r'\bonoutofsync\b',
     r'\bonoverflow(?:changed)?\b',
     r'\bonpage(?:hide|show)\b',
     r'\bonpaint\b',
     r'\bonpaste\b',
     r'\bonpause\b',
+    r'\bonplay(?:ing)?\b',
+    r'\bonpopstate\b',
     r'\bonpopup(?:hidden|hiding|showing|shown)\b',
     r'\bonprogress\b',
     r'\bonpropertychange\b',
     r'\bonradiostatechange\b',
+    r'\bonratechange\b',
     r'\bonreadystatechange\b',
     r'\bonrepeat\b',
     r'\bonreset\b',
@@ -1090,19 +1102,30 @@ _badwords = [
     r'\bonrow(?:delete|enter|exit|inserted)\b',
     r'\bonrows(?:delete|enter|inserted)\b',
     r'\bonscroll\b',
-    r'\bonseek\b',
+    r'\bonsearch\b',
+    r'\bonseek(?:ed|ing)?\b',
     r'\bonselect(?:start)?\b',
     r'\bonselectionchange\b',
+    r'\bonshow\b',
     r'\bonstart\b',
+    r'\bonstalled\b',
     r'\bonstop\b',
+    r'\bonstorage\b',
     r'\bonsubmit\b',
+    r'\bonsuspend\b',
     r'\bonsync(?:from|to)preference\b',
     r'\bonsyncrestored\b',
     r'\bontext\b',
-    r'\bontimeerror\b',
+    r'\bontime(?:error|update)\b',
+    r'\bontoggle\b',
+    r'\bontouch(?:cancel|end|move|start)\b',
     r'\bontrackchange\b',
+    r'\b(?:on)?transitionend\b',
     r'\bonunderflow\b',
     r'\bonurlflip\b',
+    r'\bonvolumechange\b',
+    r'\bonwaiting\b',
+    r'\bonwheel\b',
     r'\bseeksegmenttime\b',
     r'\bsvgabort\b',
     r'\bsvgerror\b',
-- 
cgit v1.2.3


From 3f4ed2805b0bf1f877a6717e6d15d8d351cc924e Mon Sep 17 00:00:00 2001
From: Mark Sapiro <mark@msapiro.net>
Date: Mon, 12 Mar 2018 17:36:25 -0700
Subject: Fixed another Python 2.7 dependency.

---
 Mailman/Handlers/ToDigest.py | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

(limited to 'Mailman')

diff --git a/Mailman/Handlers/ToDigest.py b/Mailman/Handlers/ToDigest.py
index 046cbaba..15042075 100644
--- a/Mailman/Handlers/ToDigest.py
+++ b/Mailman/Handlers/ToDigest.py
@@ -72,10 +72,9 @@ def to_cset_out(text, lcset):
     # Convert text from unicode or lcset to output cset.
     ocset = Charset(lcset).get_output_charset() or lcset
     if isinstance(text, unicode):
-        return text.encode(ocset, errors='replace')
+        return text.encode(ocset, 'replace')
     else:
-        return text.decode(lcset, errors='replace').encode(ocset,
-                                                           errors='replace')
+        return text.decode(lcset, 'replace').encode(ocset, 'replace')
 
 
 
-- 
cgit v1.2.3


From a942e159e5c738072efa8fa8c4d7c76cc35a7db5 Mon Sep 17 00:00:00 2001
From: Mark Sapiro <mark@msapiro.net>
Date: Tue, 10 Apr 2018 20:34:48 -0700
Subject: Improve DELIVERY_RETRY_WAIT reimplementation.

---
 Mailman/Queue/OutgoingRunner.py | 8 ++++----
 Mailman/Queue/RetryRunner.py    | 7 +++++--
 2 files changed, 9 insertions(+), 6 deletions(-)

(limited to 'Mailman')

diff --git a/Mailman/Queue/OutgoingRunner.py b/Mailman/Queue/OutgoingRunner.py
index 0a204e66..86d26808 100755
--- a/Mailman/Queue/OutgoingRunner.py
+++ b/Mailman/Queue/OutgoingRunner.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2000-2017 by the Free Software Foundation, Inc.
+# Copyright (C) 2000-2018 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -122,12 +122,12 @@ class OutgoingRunner(Runner, BounceMixin):
                         # disposition?
                         if now > deliver_until:
                             return False
-                        # We're going to retry, but not too soon.
-                        deliver_after = now + mm_cfg.DELIVERY_RETRY_WAIT
-                        msgdata['deliver_after'] = deliver_after
                     else:
                         # Keep trying to delivery this message for a while
                         deliver_until = now + mm_cfg.DELIVERY_RETRY_PERIOD
+                    # Don't retry delivery too soon.
+                    deliver_after = now + mm_cfg.DELIVERY_RETRY_WAIT
+                    msgdata['deliver_after'] = deliver_after
                     msgdata['last_recip_count'] = len(recips)
                     msgdata['deliver_until'] = deliver_until
                     msgdata['recips'] = recips
diff --git a/Mailman/Queue/RetryRunner.py b/Mailman/Queue/RetryRunner.py
index 66244253..49aa484d 100644
--- a/Mailman/Queue/RetryRunner.py
+++ b/Mailman/Queue/RetryRunner.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2003 by the Free Software Foundation, Inc.
+# Copyright (C) 2003-2018 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -37,7 +37,10 @@ class RetryRunner(Runner):
         self.__outq = Switchboard(mm_cfg.OUTQUEUE_DIR)
 
     def _dispose(self, mlist, msg, msgdata):
-        # Move it to the out queue for another retry
+        # Move it to the out queue for another retry if it's time.
+        deliver_after = msgdata.get('deliver_after', 0)
+        if time.time() < deliver_after:
+            return True
         self.__outq.enqueue(msg, msgdata)
         return False
 
-- 
cgit v1.2.3