[Pkg-mailman-hackers] Pkg-mailman commit - rev 388 - trunk/debian/patches

Hector Garcia hector at costa.debian.org
Wed Sep 20 18:51:59 UTC 2006


Author: hector
Date: 2006-09-20 18:51:59 +0000 (Wed, 20 Sep 2006)
New Revision: 388

Added:
   trunk/debian/patches/23_CVE-2006-3636.patch
   trunk/debian/patches/24_CVE-2006-2941.patch
   trunk/debian/patches/25_CVE-2006-4624.patch
Removed:
   trunk/debian/patches/23_CVE-2006-3636.dpatch
   trunk/debian/patches/24_CVE-2006-2941.dpatch
   trunk/debian/patches/25_CVE-2006-4624.dpatch
Modified:
   trunk/debian/patches/series
Log:
Rename patches

Deleted: trunk/debian/patches/23_CVE-2006-3636.dpatch
===================================================================
--- trunk/debian/patches/23_CVE-2006-3636.dpatch	2006-09-20 18:49:40 UTC (rev 387)
+++ trunk/debian/patches/23_CVE-2006-3636.dpatch	2006-09-20 18:51:59 UTC (rev 388)
@@ -1,249 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 72_CVE-2006-3636.dpatch by  <lionel at mamane.lu>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: CVE-2006-3636.  Fixes for various cross-site scripting issues.
-## DP: Discovery by Moritz Naumann and most of the repair work done by
-## DP: Mark Sapiro (with some additional work by Barry).
-
-
- at DPATCH@
-Index: Mailman/Cgi/admin.py
-===================================================================
---- Mailman/Cgi/admin.py.orig	2005-12-30 19:50:07.000000000 +0100
-+++ Mailman/Cgi/admin.py	2006-09-19 22:57:38.000000000 +0200
-@@ -1318,6 +1318,7 @@
-         # we display.  Try uploading a file with 10k names -- it takes a while
-         # to render the status page.
-         for entry in entries:
-+            safeentry = Utils.websafe(entry)
-             fullname, address = parseaddr(entry)
-             # Canonicalize the full name
-             fullname = Utils.canonstr(fullname, mlist.preferred_language)
-@@ -1335,20 +1336,20 @@
-                                             send_admin_notif, invitation,
-                                             whence='admin mass sub')
-             except Errors.MMAlreadyAMember:
--                subscribe_errors.append((entry, _('Already a member')))
-+                subscribe_errors.append((safeentry, _('Already a member')))
-             except Errors.MMBadEmailError:
-                 if userdesc.address == '':
-                     subscribe_errors.append((_('&lt;blank line&gt;'),
-                                              _('Bad/Invalid email address')))
-                 else:
--                    subscribe_errors.append((entry,
-+                    subscribe_errors.append((safeentry,
-                                              _('Bad/Invalid email address')))
-             except Errors.MMHostileAddress:
-                 subscribe_errors.append(
--                    (entry, _('Hostile address (illegal characters)')))
-+                    (safeentry, _('Hostile address (illegal characters)')))
-             except Errors.MembershipIsBanned, pattern:
-                 subscribe_errors.append(
--                    (entry, _('Banned address (matched %(pattern)s)')))
-+                    (safeentry, _('Banned address (matched %(pattern)s)')))
-             else:
-                 member = Utils.uncanonstr(formataddr((fullname, address)))
-                 subscribe_success.append(Utils.websafe(member))
-@@ -1388,9 +1389,9 @@
-                     addr, whence='admin mass unsub',
-                     admin_notif=send_unsub_notifications,
-                     userack=userack)
--                unsubscribe_success.append(addr)
-+                unsubscribe_success.append(Utils.websafe(addr))
-             except Errors.NotAMemberError:
--                unsubscribe_errors.append(addr)
-+                unsubscribe_errors.append(Utils.websafe(addr))
-         if unsubscribe_success:
-             doc.AddItem(Header(5, _('Successfully Unsubscribed:')))
-             doc.AddItem(UnorderedList(*unsubscribe_success))
-Index: Mailman/Cgi/admindb.py
-===================================================================
---- Mailman/Cgi/admindb.py.orig	2005-12-30 19:50:07.000000000 +0100
-+++ Mailman/Cgi/admindb.py	2006-09-19 22:48:50.000000000 +0200
-@@ -313,7 +313,7 @@
-                      '&nbsp;' + _('Permanently ban from this list')
-         # While the address may be a unicode, it must be ascii
-         paddr = addr.encode('us-ascii', 'replace')
--        table.AddRow(['%s<br><em>%s</em>' % (paddr, fullname),
-+        table.AddRow(['%s<br><em>%s</em>' % (paddr, Utils.websafe(fullname)),
-                       radio,
-                       TextBox('comment-%d' % id, size=40)
-                       ])
-@@ -357,7 +357,7 @@
-             mlist.HandleRequest(id, mm_cfg.DISCARD)
-             continue
-         num += 1
--        table.AddRow(['%s<br><em>%s</em>' % (addr, fullname),
-+        table.AddRow(['%s<br><em>%s</em>' % (addr, Utils.websafe(fullname)),
-                       RadioButtonArray(id, (_('Defer'),
-                                             _('Approve'),
-                                             _('Reject'),
-Index: Mailman/Cgi/create.py
-===================================================================
---- Mailman/Cgi/create.py.orig	2005-12-30 19:50:07.000000000 +0100
-+++ Mailman/Cgi/create.py	2006-09-19 22:48:50.000000000 +0200
-@@ -190,15 +190,24 @@
-                 mlist.Create(listname, owner, pw, langs, emailhost)
-             finally:
-                 os.umask(oldmask)
--        except Errors.EmailAddressError, s:
-+        except Errors.EmailAddressError, e:
-+            if e.args:
-+                s = Utils.websafe(e.args[0])
-+            else:
-+                s = Utils.websafe(owner)
-             request_creation(doc, cgidata,
-                              _('Bad owner email address: %(s)s'))
-             return
-         except Errors.MMListAlreadyExistsError:
-+            # MAS: List already exists so we don't need to websafe it.
-             request_creation(doc, cgidata,
-                              _('List already exists: %(listname)s'))
-             return
--        except Errors.BadListNameError, s:
-+        except Errors.BadListNameError, e:
-+            if e.args:
-+                s = Utils.websafe(e.args[0])
-+            else:
-+                s = Utils.websafe(listname)
-             request_creation(doc, cgidata,
-                              _('Illegal list name: %(s)s'))
-             return
-@@ -321,15 +330,17 @@
-     ftable.AddRow([Center(Italic(_('List Identity')))])
-     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, colspan=2)
- 
--    safelistname = Utils.websafe(cgidata.getvalue('listname', ''))
-+    listname = cgidata.getvalue('listname', '')
-+    # MAS: Don't websafe twice.  TextBox does it.
-     ftable.AddRow([Label(_('Name of list:')),
--                   TextBox('listname', safelistname)])
-+                   TextBox('listname', listname)])
-     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, bgcolor=GREY)
-     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 1, bgcolor=GREY)
- 
--    safeowner = Utils.websafe(cgidata.getvalue('owner', ''))
-+    owner = cgidata.getvalue('owner', '')
-+    # MAS: Don't websafe twice.  TextBox does it.
-     ftable.AddRow([Label(_('Initial list owner address:')),
--                   TextBox('owner', safeowner)])
-+                   TextBox('owner', owner)])
-     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, bgcolor=GREY)
-     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 1, bgcolor=GREY)
- 
-Index: Mailman/Cgi/edithtml.py
-===================================================================
---- Mailman/Cgi/edithtml.py.orig	2006-01-09 08:06:52.000000000 +0100
-+++ Mailman/Cgi/edithtml.py	2006-09-19 22:48:50.000000000 +0200
-@@ -143,7 +143,8 @@
-     doc.AddItem('<p>')
-     doc.AddItem('<hr>')
-     form = Form(mlist.GetScriptURL('edithtml') + '/' + template_name)
--    text = Utils.websafe(Utils.maketext(template_name, raw=1, mlist=mlist))
-+    text = Utils.maketext(template_name, raw=1, mlist=mlist)
-+    # MAS: Don't websafe twice.  TextArea does it.
-     form.AddItem(TextArea('html_code', text, rows=40, cols=75))
-     form.AddItem('<p>' + _('When you are done making changes...'))
-     form.AddItem(SubmitButton('submit', _('Submit Changes')))
-Index: Mailman/Cgi/options.py
-===================================================================
---- Mailman/Cgi/options.py.orig	2005-12-03 02:07:13.000000000 +0100
-+++ Mailman/Cgi/options.py	2006-09-19 22:48:50.000000000 +0200
-@@ -702,7 +702,7 @@
- 
-     fullname = Utils.uncanonstr(mlist.getMemberName(user), userlang)
-     if fullname:
--        presentable_user += ', %s' % fullname
-+        presentable_user += ', %s' % Utils.websafe(fullname)
- 
-     # Do replacements
-     replacements = mlist.GetStandardReplacements(userlang)
-Index: Mailman/Gui/General.py
-===================================================================
---- Mailman/Gui/General.py.orig	2006-03-23 11:51:25.000000000 +0100
-+++ Mailman/Gui/General.py	2006-09-19 22:48:50.000000000 +0200
-@@ -439,13 +439,13 @@
-             GUIBase._setValue(self, mlist, property, val, doc)
- 
-     def _escape(self, property, value):
--        # The 'info' property allows HTML, but lets sanitize it to avoid XSS
-+        # The 'info' property allows HTML, but let's sanitize it to avoid XSS
-         # exploits.  Everything else should be fully escaped.
-         if property <> 'info':
-             return GUIBase._escape(self, property, value)
-         # Sanitize <script> and </script> tags but nothing else.  Not the best
-         # solution, but expedient.
--        return re.sub(r'<([/]?script.*?)>', r'&lt;\1&gt;', value)
-+        return re.sub(r'(?i)<([/]?script.*?)>', r'&lt;\1&gt;', value)
- 
-     def _postValidate(self, mlist, doc):
-         if not mlist.reply_to_address.strip() and \
-Index: Mailman/HTMLFormatter.py
-===================================================================
---- Mailman/HTMLFormatter.py.orig	2005-08-27 03:40:15.000000000 +0200
-+++ Mailman/HTMLFormatter.py	2006-09-19 22:48:50.000000000 +0200
-@@ -1,4 +1,4 @@
--# Copyright (C) 1998-2003 by the Free Software Foundation, Inc.
-+# Copyright (C) 1998-2006 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
-@@ -332,8 +332,12 @@
-         return '</FORM>'
- 
-     def FormatBox(self, name, size=20, value=''):
-+        if isinstance(value, str):
-+            safevalue = Utils.websafe(value)
-+        else:
-+            safevalue = value
-         return '<INPUT type="Text" name="%s" size="%d" value="%s">' % (
--            name, size, value)
-+            name, size, safevalue)
- 
-     def FormatSecureBox(self, name):
-         return '<INPUT type="Password" name="%s" size="15">' % name
-Index: Mailman/Utils.py
-===================================================================
---- Mailman/Utils.py.orig	2006-03-18 18:23:04.000000000 +0100
-+++ Mailman/Utils.py	2006-09-19 22:48:50.000000000 +0200
-@@ -204,7 +204,7 @@
- _badchars = re.compile(r'[][()<>|;^,\000-\037\177-\377]')
- 
- def ValidateEmail(s):
--    """Verify that the an email address isn't grossly evil."""
-+    """Verify that an email address isn't grossly evil."""
-     # Pretty minimal, cheesy check.  We could do better...
-     if not s or s.count(' ') > 0:
-         raise Errors.MMBadEmailError
-Index: Mailman/htmlformat.py
-===================================================================
---- Mailman/htmlformat.py.orig	2005-08-27 03:40:15.000000000 +0200
-+++ Mailman/htmlformat.py	2006-09-19 22:48:50.000000000 +0200
-@@ -448,7 +448,11 @@
- 
- class TextBox(InputObj):
-     def __init__(self, name, value='', size=mm_cfg.TEXTFIELDWIDTH):
--        InputObj.__init__(self, name, "TEXT", value, checked=0, size=size)
-+        if isinstance(value, str):
-+            safevalue = Utils.websafe(value)
-+        else:
-+            safevalue = value
-+        InputObj.__init__(self, name, "TEXT", safevalue, checked=0, size=size)
- 
- class Hidden(InputObj):
-     def __init__(self, name, value=''):
-@@ -457,8 +461,12 @@
- class TextArea:
-     def __init__(self, name, text='', rows=None, cols=None, wrap='soft',
-                  readonly=0):
-+        if isinstance(text, str):
-+            safetext = Utils.websafe(text)
-+        else:
-+            safetext = text
-         self.name = name
--        self.text = text
-+        self.text = safetext
-         self.rows = rows
-         self.cols = cols
-         self.wrap = wrap

Copied: trunk/debian/patches/23_CVE-2006-3636.patch (from rev 386, trunk/debian/patches/23_CVE-2006-3636.dpatch)
===================================================================
--- trunk/debian/patches/23_CVE-2006-3636.patch	                        (rev 0)
+++ trunk/debian/patches/23_CVE-2006-3636.patch	2006-09-20 18:51:59 UTC (rev 388)
@@ -0,0 +1,249 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 72_CVE-2006-3636.dpatch by  <lionel at mamane.lu>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: CVE-2006-3636.  Fixes for various cross-site scripting issues.
+## DP: Discovery by Moritz Naumann and most of the repair work done by
+## DP: Mark Sapiro (with some additional work by Barry).
+
+
+ at DPATCH@
+Index: Mailman/Cgi/admin.py
+===================================================================
+--- Mailman/Cgi/admin.py.orig	2005-12-30 19:50:07.000000000 +0100
++++ Mailman/Cgi/admin.py	2006-09-19 22:57:38.000000000 +0200
+@@ -1318,6 +1318,7 @@
+         # we display.  Try uploading a file with 10k names -- it takes a while
+         # to render the status page.
+         for entry in entries:
++            safeentry = Utils.websafe(entry)
+             fullname, address = parseaddr(entry)
+             # Canonicalize the full name
+             fullname = Utils.canonstr(fullname, mlist.preferred_language)
+@@ -1335,20 +1336,20 @@
+                                             send_admin_notif, invitation,
+                                             whence='admin mass sub')
+             except Errors.MMAlreadyAMember:
+-                subscribe_errors.append((entry, _('Already a member')))
++                subscribe_errors.append((safeentry, _('Already a member')))
+             except Errors.MMBadEmailError:
+                 if userdesc.address == '':
+                     subscribe_errors.append((_('&lt;blank line&gt;'),
+                                              _('Bad/Invalid email address')))
+                 else:
+-                    subscribe_errors.append((entry,
++                    subscribe_errors.append((safeentry,
+                                              _('Bad/Invalid email address')))
+             except Errors.MMHostileAddress:
+                 subscribe_errors.append(
+-                    (entry, _('Hostile address (illegal characters)')))
++                    (safeentry, _('Hostile address (illegal characters)')))
+             except Errors.MembershipIsBanned, pattern:
+                 subscribe_errors.append(
+-                    (entry, _('Banned address (matched %(pattern)s)')))
++                    (safeentry, _('Banned address (matched %(pattern)s)')))
+             else:
+                 member = Utils.uncanonstr(formataddr((fullname, address)))
+                 subscribe_success.append(Utils.websafe(member))
+@@ -1388,9 +1389,9 @@
+                     addr, whence='admin mass unsub',
+                     admin_notif=send_unsub_notifications,
+                     userack=userack)
+-                unsubscribe_success.append(addr)
++                unsubscribe_success.append(Utils.websafe(addr))
+             except Errors.NotAMemberError:
+-                unsubscribe_errors.append(addr)
++                unsubscribe_errors.append(Utils.websafe(addr))
+         if unsubscribe_success:
+             doc.AddItem(Header(5, _('Successfully Unsubscribed:')))
+             doc.AddItem(UnorderedList(*unsubscribe_success))
+Index: Mailman/Cgi/admindb.py
+===================================================================
+--- Mailman/Cgi/admindb.py.orig	2005-12-30 19:50:07.000000000 +0100
++++ Mailman/Cgi/admindb.py	2006-09-19 22:48:50.000000000 +0200
+@@ -313,7 +313,7 @@
+                      '&nbsp;' + _('Permanently ban from this list')
+         # While the address may be a unicode, it must be ascii
+         paddr = addr.encode('us-ascii', 'replace')
+-        table.AddRow(['%s<br><em>%s</em>' % (paddr, fullname),
++        table.AddRow(['%s<br><em>%s</em>' % (paddr, Utils.websafe(fullname)),
+                       radio,
+                       TextBox('comment-%d' % id, size=40)
+                       ])
+@@ -357,7 +357,7 @@
+             mlist.HandleRequest(id, mm_cfg.DISCARD)
+             continue
+         num += 1
+-        table.AddRow(['%s<br><em>%s</em>' % (addr, fullname),
++        table.AddRow(['%s<br><em>%s</em>' % (addr, Utils.websafe(fullname)),
+                       RadioButtonArray(id, (_('Defer'),
+                                             _('Approve'),
+                                             _('Reject'),
+Index: Mailman/Cgi/create.py
+===================================================================
+--- Mailman/Cgi/create.py.orig	2005-12-30 19:50:07.000000000 +0100
++++ Mailman/Cgi/create.py	2006-09-19 22:48:50.000000000 +0200
+@@ -190,15 +190,24 @@
+                 mlist.Create(listname, owner, pw, langs, emailhost)
+             finally:
+                 os.umask(oldmask)
+-        except Errors.EmailAddressError, s:
++        except Errors.EmailAddressError, e:
++            if e.args:
++                s = Utils.websafe(e.args[0])
++            else:
++                s = Utils.websafe(owner)
+             request_creation(doc, cgidata,
+                              _('Bad owner email address: %(s)s'))
+             return
+         except Errors.MMListAlreadyExistsError:
++            # MAS: List already exists so we don't need to websafe it.
+             request_creation(doc, cgidata,
+                              _('List already exists: %(listname)s'))
+             return
+-        except Errors.BadListNameError, s:
++        except Errors.BadListNameError, e:
++            if e.args:
++                s = Utils.websafe(e.args[0])
++            else:
++                s = Utils.websafe(listname)
+             request_creation(doc, cgidata,
+                              _('Illegal list name: %(s)s'))
+             return
+@@ -321,15 +330,17 @@
+     ftable.AddRow([Center(Italic(_('List Identity')))])
+     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, colspan=2)
+ 
+-    safelistname = Utils.websafe(cgidata.getvalue('listname', ''))
++    listname = cgidata.getvalue('listname', '')
++    # MAS: Don't websafe twice.  TextBox does it.
+     ftable.AddRow([Label(_('Name of list:')),
+-                   TextBox('listname', safelistname)])
++                   TextBox('listname', listname)])
+     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, bgcolor=GREY)
+     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 1, bgcolor=GREY)
+ 
+-    safeowner = Utils.websafe(cgidata.getvalue('owner', ''))
++    owner = cgidata.getvalue('owner', '')
++    # MAS: Don't websafe twice.  TextBox does it.
+     ftable.AddRow([Label(_('Initial list owner address:')),
+-                   TextBox('owner', safeowner)])
++                   TextBox('owner', owner)])
+     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, bgcolor=GREY)
+     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 1, bgcolor=GREY)
+ 
+Index: Mailman/Cgi/edithtml.py
+===================================================================
+--- Mailman/Cgi/edithtml.py.orig	2006-01-09 08:06:52.000000000 +0100
++++ Mailman/Cgi/edithtml.py	2006-09-19 22:48:50.000000000 +0200
+@@ -143,7 +143,8 @@
+     doc.AddItem('<p>')
+     doc.AddItem('<hr>')
+     form = Form(mlist.GetScriptURL('edithtml') + '/' + template_name)
+-    text = Utils.websafe(Utils.maketext(template_name, raw=1, mlist=mlist))
++    text = Utils.maketext(template_name, raw=1, mlist=mlist)
++    # MAS: Don't websafe twice.  TextArea does it.
+     form.AddItem(TextArea('html_code', text, rows=40, cols=75))
+     form.AddItem('<p>' + _('When you are done making changes...'))
+     form.AddItem(SubmitButton('submit', _('Submit Changes')))
+Index: Mailman/Cgi/options.py
+===================================================================
+--- Mailman/Cgi/options.py.orig	2005-12-03 02:07:13.000000000 +0100
++++ Mailman/Cgi/options.py	2006-09-19 22:48:50.000000000 +0200
+@@ -702,7 +702,7 @@
+ 
+     fullname = Utils.uncanonstr(mlist.getMemberName(user), userlang)
+     if fullname:
+-        presentable_user += ', %s' % fullname
++        presentable_user += ', %s' % Utils.websafe(fullname)
+ 
+     # Do replacements
+     replacements = mlist.GetStandardReplacements(userlang)
+Index: Mailman/Gui/General.py
+===================================================================
+--- Mailman/Gui/General.py.orig	2006-03-23 11:51:25.000000000 +0100
++++ Mailman/Gui/General.py	2006-09-19 22:48:50.000000000 +0200
+@@ -439,13 +439,13 @@
+             GUIBase._setValue(self, mlist, property, val, doc)
+ 
+     def _escape(self, property, value):
+-        # The 'info' property allows HTML, but lets sanitize it to avoid XSS
++        # The 'info' property allows HTML, but let's sanitize it to avoid XSS
+         # exploits.  Everything else should be fully escaped.
+         if property <> 'info':
+             return GUIBase._escape(self, property, value)
+         # Sanitize <script> and </script> tags but nothing else.  Not the best
+         # solution, but expedient.
+-        return re.sub(r'<([/]?script.*?)>', r'&lt;\1&gt;', value)
++        return re.sub(r'(?i)<([/]?script.*?)>', r'&lt;\1&gt;', value)
+ 
+     def _postValidate(self, mlist, doc):
+         if not mlist.reply_to_address.strip() and \
+Index: Mailman/HTMLFormatter.py
+===================================================================
+--- Mailman/HTMLFormatter.py.orig	2005-08-27 03:40:15.000000000 +0200
++++ Mailman/HTMLFormatter.py	2006-09-19 22:48:50.000000000 +0200
+@@ -1,4 +1,4 @@
+-# Copyright (C) 1998-2003 by the Free Software Foundation, Inc.
++# Copyright (C) 1998-2006 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
+@@ -332,8 +332,12 @@
+         return '</FORM>'
+ 
+     def FormatBox(self, name, size=20, value=''):
++        if isinstance(value, str):
++            safevalue = Utils.websafe(value)
++        else:
++            safevalue = value
+         return '<INPUT type="Text" name="%s" size="%d" value="%s">' % (
+-            name, size, value)
++            name, size, safevalue)
+ 
+     def FormatSecureBox(self, name):
+         return '<INPUT type="Password" name="%s" size="15">' % name
+Index: Mailman/Utils.py
+===================================================================
+--- Mailman/Utils.py.orig	2006-03-18 18:23:04.000000000 +0100
++++ Mailman/Utils.py	2006-09-19 22:48:50.000000000 +0200
+@@ -204,7 +204,7 @@
+ _badchars = re.compile(r'[][()<>|;^,\000-\037\177-\377]')
+ 
+ def ValidateEmail(s):
+-    """Verify that the an email address isn't grossly evil."""
++    """Verify that an email address isn't grossly evil."""
+     # Pretty minimal, cheesy check.  We could do better...
+     if not s or s.count(' ') > 0:
+         raise Errors.MMBadEmailError
+Index: Mailman/htmlformat.py
+===================================================================
+--- Mailman/htmlformat.py.orig	2005-08-27 03:40:15.000000000 +0200
++++ Mailman/htmlformat.py	2006-09-19 22:48:50.000000000 +0200
+@@ -448,7 +448,11 @@
+ 
+ class TextBox(InputObj):
+     def __init__(self, name, value='', size=mm_cfg.TEXTFIELDWIDTH):
+-        InputObj.__init__(self, name, "TEXT", value, checked=0, size=size)
++        if isinstance(value, str):
++            safevalue = Utils.websafe(value)
++        else:
++            safevalue = value
++        InputObj.__init__(self, name, "TEXT", safevalue, checked=0, size=size)
+ 
+ class Hidden(InputObj):
+     def __init__(self, name, value=''):
+@@ -457,8 +461,12 @@
+ class TextArea:
+     def __init__(self, name, text='', rows=None, cols=None, wrap='soft',
+                  readonly=0):
++        if isinstance(text, str):
++            safetext = Utils.websafe(text)
++        else:
++            safetext = text
+         self.name = name
+-        self.text = text
++        self.text = safetext
+         self.rows = rows
+         self.cols = cols
+         self.wrap = wrap

Deleted: trunk/debian/patches/24_CVE-2006-2941.dpatch
===================================================================
--- trunk/debian/patches/24_CVE-2006-2941.dpatch	2006-09-20 18:49:40 UTC (rev 387)
+++ trunk/debian/patches/24_CVE-2006-2941.dpatch	2006-09-20 18:51:59 UTC (rev 388)
@@ -1,441 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 73_CVE-2006-2941.dpatch by  <lionel at mamane.lu>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: CVE-2006-2941: DoS caused by standards-breaking RFC 2231 formatted headers.
-
- at DPATCH@
-Index: misc/CVE-2006-2941.patch
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ misc/CVE-2006-2941.patch	2006-09-19 23:02:23.000000000 +0200
-@@ -0,0 +1,414 @@
-+diff --recursive -u email-2.5.7/email/__init__.py email-2.5.8/email/__init__.py
-+--- email-2.5.7/email/__init__.py	2006-03-06 01:23:54.000000000 +0100
-++++ email-2.5.8/email/__init__.py	2006-07-25 15:10:39.000000000 +0200
-+@@ -3,7 +3,7 @@
-+
-+ """A package for parsing, handling, and generating email messages."""
-+
-+-__version__ = '2.5.5'
-++__version__ = '2.5.5.debian1'
-+
-+ __all__ = [
-+     'base64MIME',
-+diff --recursive -u email-2.5.7/email/_parseaddr.py email-2.5.8/email/_parseaddr.py
-+--- email-2.5.7/email/_parseaddr.py	2006-03-06 01:23:54.000000000 +0100
-++++ email-2.5.8/email/_parseaddr.py	2006-06-13 05:43:49.000000000 +0200
-+@@ -365,6 +365,7 @@
-+                 break
-+             elif allowcomments and self.field[self.pos] == '(':
-+                 slist.append(self.getcomment())
-++                continue        # have already advanced pos from getcomment
-+             elif self.field[self.pos] == '\\':
-+                 quote = True
-+             else:
-+diff --recursive -u email-2.5.7/email/test/test_email.py email-2.5.8/email/test/test_email.py
-+--- email-2.5.7/email/test/test_email.py	2006-03-06 01:23:53.000000000 +0100
-++++ email-2.5.8/email/test/test_email.py	2006-07-26 05:58:13.000000000 +0200
-+@@ -9,7 +9,7 @@
-+ import unittest
-+ import warnings
-+ from cStringIO import StringIO
-+-from types import StringType, ListType
-++from types import StringType, ListType, TupleType
-+
-+ import email
-+
-+@@ -2064,6 +2064,12 @@
-+            ['foo: ;', '"Jason R. Mastaler" <jason at dom.ain>']),
-+            [('', ''), ('Jason R. Mastaler', 'jason at dom.ain')])
-+
-++    def test_getaddresses_embedded_comment(self):
-++        """Test proper handling of a nested comment"""
-++        eq = self.assertEqual
-++        addrs = Utils.getaddresses(['User ((nested comment)) <foo at bar.com>'])
-++        eq(addrs[0][1], 'foo at bar.com')
-++
-+     def test_utils_quote_unquote(self):
-+         eq = self.assertEqual
-+         msg = Message()
-+@@ -2750,14 +2756,17 @@
-+
-+ '''
-+         msg = email.message_from_string(m)
-+-        self.assertEqual(msg.get_param('NAME'),
-+-                         (None, None, 'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm'))
-++        param = msg.get_param('NAME')
-++        self.failIf(isinstance(param, TupleType))
-++        self.assertEqual(
-++            param,
-++            'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm')
-+
-+     def test_rfc2231_no_language_or_charset_in_filename(self):
-+         m = '''\
-+ Content-Disposition: inline;
-+-\tfilename*0="This%20is%20even%20more%20";
-+-\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
-++\tfilename*0*="This%20is%20even%20more%20";
-++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
-+ \tfilename*2="is it not.pdf"
-+
-+ '''
-+@@ -2768,8 +2777,8 @@
-+     def test_rfc2231_no_language_or_charset_in_boundary(self):
-+         m = '''\
-+ Content-Type: multipart/alternative;
-+-\tboundary*0="This%20is%20even%20more%20";
-+-\tboundary*1="%2A%2A%2Afun%2A%2A%2A%20";
-++\tboundary*0*="This%20is%20even%20more%20";
-++\tboundary*1*="%2A%2A%2Afun%2A%2A%2A%20";
-+ \tboundary*2="is it not.pdf"
-+
-+ '''
-+@@ -2777,12 +2786,38 @@
-+         self.assertEqual(msg.get_boundary(),
-+                          'This is even more ***fun*** is it not.pdf')
-+
-++    def test_rfc2231_partly_encoded(self):
-++        m = '''\
-++Content-Disposition: inline;
-++\tfilename*0="''This%20is%20even%20more%20";
-++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
-++\tfilename*2="is it not.pdf"
-++
-++'''
-++        msg = email.message_from_string(m)
-++        self.assertEqual(
-++            msg.get_filename(),
-++            'This%20is%20even%20more%20***fun*** is it not.pdf')
-++
-++    def test_rfc2231_partly_nonencoded(self):
-++        m = '''\
-++Content-Disposition: inline;
-++\tfilename*0="This%20is%20even%20more%20";
-++\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
-++\tfilename*2="is it not.pdf"
-++
-++'''
-++        msg = email.message_from_string(m)
-++        self.assertEqual(
-++            msg.get_filename(),
-++            'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20is it not.pdf')
-++
-+     def test_rfc2231_no_language_or_charset_in_charset(self):
-+         # This is a nonsensical charset value, but tests the code anyway
-+         m = '''\
-+ Content-Type: text/plain;
-+-\tcharset*0="This%20is%20even%20more%20";
-+-\tcharset*1="%2A%2A%2Afun%2A%2A%2A%20";
-++\tcharset*0*="This%20is%20even%20more%20";
-++\tcharset*1*="%2A%2A%2Afun%2A%2A%2A%20";
-+ \tcharset*2="is it not.pdf"
-+
-+ '''
-+@@ -2793,8 +2828,8 @@
-+     def test_rfc2231_bad_encoding_in_filename(self):
-+         m = '''\
-+ Content-Disposition: inline;
-+-\tfilename*0="bogus'xx'This%20is%20even%20more%20";
-+-\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
-++\tfilename*0*="bogus'xx'This%20is%20even%20more%20";
-++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
-+ \tfilename*2="is it not.pdf"
-+
-+ '''
-+@@ -2825,9 +2860,9 @@
-+     def test_rfc2231_bad_character_in_filename(self):
-+         m = '''\
-+ Content-Disposition: inline;
-+-\tfilename*0="ascii'xx'This%20is%20even%20more%20";
-+-\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
-+-\tfilename*2="is it not.pdf%E2"
-++\tfilename*0*="ascii'xx'This%20is%20even%20more%20";
-++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
-++\tfilename*2*="is it not.pdf%E2"
-+
-+ '''
-+         msg = email.message_from_string(m)
-+@@ -2835,6 +2870,102 @@
-+                          'This is even more ***fun*** is it not.pdf\xe2')
-+
-+
-++    def test_rfc2231_unknown_encoding(self):
-++        m = """\
-++Content-Transfer-Encoding: 8bit
-++Content-Disposition: inline; filename*=X-UNKNOWN''myfile.txt
-++
-++"""
-++        msg = email.message_from_string(m)
-++        self.assertEqual(msg.get_filename(), 'myfile.txt')
-++
-++    def test_rfc2231_single_tick_in_filename_extended(self):
-++        eq = self.assertEqual
-++        m = """\
-++Content-Type: application/x-foo;
-++\tname*0*=\"Frank's\"; name*1*=\" Document\"
-++
-++"""
-++        msg = email.message_from_string(m)
-++        charset, language, s = msg.get_param('name')
-++        eq(charset, None)
-++        eq(language, None)
-++        eq(s, "Frank's Document")
-++
-++    def test_rfc2231_single_tick_in_filename(self):
-++        m = """\
-++Content-Type: application/x-foo; name*0=\"Frank's\"; name*1=\" Document\"
-++
-++"""
-++        msg = email.message_from_string(m)
-++        param = msg.get_param('name')
-++        self.failIf(isinstance(param, TupleType))
-++        self.assertEqual(param, "Frank's Document")
-++
-++    def test_rfc2231_tick_attack_extended(self):
-++        eq = self.assertEqual
-++        m = """\
-++Content-Type: application/x-foo;
-++\tname*0*=\"us-ascii'en-us'Frank's\"; name*1*=\" Document\"
-++
-++"""
-++        msg = email.message_from_string(m)
-++        charset, language, s = msg.get_param('name')
-++        eq(charset, 'us-ascii')
-++        eq(language, 'en-us')
-++        eq(s, "Frank's Document")
-++
-++    def test_rfc2231_tick_attack(self):
-++        m = """\
-++Content-Type: application/x-foo;
-++\tname*0=\"us-ascii'en-us'Frank's\"; name*1=\" Document\"
-++
-++"""
-++        msg = email.message_from_string(m)
-++        param = msg.get_param('name')
-++        self.failIf(isinstance(param, TupleType))
-++        self.assertEqual(param, "us-ascii'en-us'Frank's Document")
-++
-++    def test_rfc2231_no_extended_values(self):
-++        eq = self.assertEqual
-++        m = """\
-++Content-Type: application/x-foo; name=\"Frank's Document\"
-++
-++"""
-++        msg = email.message_from_string(m)
-++        eq(msg.get_param('name'), "Frank's Document")
-++
-++    def test_rfc2231_encoded_then_unencoded_segments(self):
-++        eq = self.assertEqual
-++        m = """\
-++Content-Type: application/x-foo;
-++\tname*0*=\"us-ascii'en-us'My\";
-++\tname*1=\" Document\";
-++\tname*2*=\" For You\"
-++
-++"""
-++        msg = email.message_from_string(m)
-++        charset, language, s = msg.get_param('name')
-++        eq(charset, 'us-ascii')
-++        eq(language, 'en-us')
-++        eq(s, 'My Document For You')
-++
-++    def test_rfc2231_unencoded_then_encoded_segments(self):
-++        eq = self.assertEqual
-++        m = """\
-++Content-Type: application/x-foo;
-++\tname*0=\"us-ascii'en-us'My\";
-++\tname*1*=\" Document\";
-++\tname*2*=\" For You\"
-++
-++"""
-++        msg = email.message_from_string(m)
-++        charset, language, s = msg.get_param('name')
-++        eq(charset, 'us-ascii')
-++        eq(language, 'en-us')
-++        eq(s, 'My Document For You')
-++
-++
-+ 
-+ def _testclasses():
-+     mod = sys.modules[__name__]
-+diff --recursive -u email-2.5.7/email/Utils.py email-2.5.8/email/Utils.py
-+--- email-2.5.7/email/Utils.py	2006-03-06 01:23:54.000000000 +0100
-++++ email-2.5.8/email/Utils.py	2006-07-25 15:10:39.000000000 +0200
-+@@ -1,14 +1,15 @@
-+-# Copyright (C) 2001,2002 Python Software Foundation
-+-# Author: barry at zope.com (Barry Warsaw)
-++# Copyright (C) 2001-2006 Python Software Foundation
-++# Author: Barry Warsaw
-++# Contact: email-sig at python.org
-+
-+-"""Miscellaneous utilities.
-+-"""
-++"""Miscellaneous utilities."""
-+
-+ import time
-+ import socket
-+ import re
-+ import random
-+ import os
-++import urllib
-+ import warnings
-+ from cStringIO import StringIO
-+ from types import ListType
-+@@ -53,6 +54,7 @@
-+ EMPTYSTRING = ''
-+ UEMPTYSTRING = u''
-+ CRLF = '\r\n'
-++TICK = "'"
-+
-+ specialsre = re.compile(r'[][\\()<>@,:;".]')
-+ escapesre = re.compile(r'[][\\()"]')
-+@@ -277,12 +279,14 @@
-+ # RFC2231-related functions - parameter encoding and decoding
-+ def decode_rfc2231(s):
-+     """Decode string according to RFC 2231"""
-+-    import urllib
-+-    parts = s.split("'", 2)
-+-    if len(parts) == 1:
-++    parts = s.split(TICK, 2)
-++    if len(parts) <= 2:
-+         return None, None, urllib.unquote(s)
-+-    charset, language, s = parts
-+-    return charset, language, urllib.unquote(s)
-++    if len(parts) > 3:
-++        charset, language = pars[:2]
-++        s = TICK.join(parts[2:])
-++        return charset, language, s
-++    return parts
-+
-+
-+ def encode_rfc2231(s, charset=None, language=None):
-+@@ -306,35 +310,52 @@
-+ def decode_params(params):
-+     """Decode parameters list according to RFC 2231.
-+
-+-    params is a sequence of 2-tuples containing (content type, string value).
-++    params is a sequence of 2-tuples containing (param name, string value).
-+     """
-++    # Copy params so we don't mess with the original
-++    params = params[:]
-+     new_params = []
-+-    # maps parameter's name to a list of continuations
-++    # Map parameter's name to a list of continuations.  The values are a
-++    # 3-tuple of the continuation number, the string value, and a flag
-++    # specifying whether a particular segment is %-encoded.
-+     rfc2231_params = {}
-+-    # params is a sequence of 2-tuples containing (content_type, string value)
-+-    name, value = params[0]
-++    name, value = params.pop(0)
-+     new_params.append((name, value))
-+-    # Cycle through each of the rest of the parameters.
-+-    for name, value in params[1:]:
-++    while params:
-++        name, value = params.pop(0)
-++        if name.endswith('*'):
-++            encoded = True
-++        else:
-++            encoded = False
-+         value = unquote(value)
-+         mo = rfc2231_continuation.match(name)
-+         if mo:
-+             name, num = mo.group('name', 'num')
-+             if num is not None:
-+                 num = int(num)
-+-            rfc2231_param1 = rfc2231_params.setdefault(name, [])
-+-            rfc2231_param1.append((num, value))
-++            rfc2231_params.setdefault(name, []).append((num, value, encoded))
-+         else:
-+             new_params.append((name, '"%s"' % quote(value)))
-+     if rfc2231_params:
-+         for name, continuations in rfc2231_params.items():
-+             value = []
-++            extended = False
-+             # Sort by number
-+             continuations.sort()
-+-            # And now append all values in num order
-+-            for num, continuation in continuations:
-+-                value.append(continuation)
-+-            charset, language, value = decode_rfc2231(EMPTYSTRING.join(value))
-+-            new_params.append(
-+-                (name, (charset, language, '"%s"' % quote(value))))
-++            # And now append all values in numerical order, converting
-++            # %-encodings for the encoded segments.  If any of the
-++            # continuation names ends in a *, then the entire string, after
-++            # decoding segments and concatenating, must have the charset and
-++            # language specifiers at the beginning of the string.
-++            for num, s, encoded in continuations:
-++                if encoded:
-++                    s = urllib.unquote(s)
-++                    extended = True
-++                value.append(s)
-++            value = quote(EMPTYSTRING.join(value))
-++            if extended:
-++                charset, language, value = decode_rfc2231(value)
-++                new_params.append((name, (charset, language, '"%s"' % value)))
-++            else:
-++                new_params.append((name, '"%s"' % value))
-+     return new_params
-+diff --recursive -u email-2.5.7/PKG-INFO email-2.5.8/PKG-INFO
-+--- email-2.5.7/PKG-INFO	2006-03-06 02:39:57.000000000 +0100
-++++ email-2.5.8/PKG-INFO	2006-07-26 06:15:58.000000000 +0200
-+@@ -1,10 +1,10 @@
-+ Metadata-Version: 1.0
-+ Name: email
-+-Version: 2.5.5
-++Version: 2.5.5.debian1
-+ Summary: Standalone email package
-+ Home-page: http://www.python.org/sigs/email-sig
-+ Author: Barry Warsaw
-+-Author-email: barry at python.org
-++Author-email: email-sig at python.org
-+ License: UNKNOWN
-+ Description: UNKNOWN
-+ Platform: UNKNOWN
-+diff --recursive -u email-2.5.7/setup.py email-2.5.8/setup.py
-+--- email-2.5.7/setup.py	2006-03-06 01:21:59.000000000 +0100
-++++ email-2.5.8/setup.py	2006-07-25 16:08:43.000000000 +0200
-+@@ -1,5 +1,3 @@
-+-#! /usr/bin/env python
-+-#
-+ # Copyright (C) 2001-2006 Python Software Foundation
-+
-+ # Standard distutils setup.py install script for the `mimelib' library, a next
-+@@ -20,7 +18,7 @@
-+       version=email.__version__,
-+       description='Standalone email package',
-+       author='Barry Warsaw',
-+-      author_email='barry at python.org',
-++      author_email='email-sig at python.org',
-+       url='http://www.python.org/sigs/email-sig',
-+       packages=['email'],
-+       )
-+diff --recursive -u email-2.5.7/testall.py email-2.5.8/testall.py
-+--- email-2.5.7/testall.py	2006-03-06 01:21:59.000000000 +0100
-++++ email-2.5.8/testall.py	2006-07-25 16:09:00.000000000 +0200
-+@@ -13,8 +13,8 @@
-+ """
-+
-+ import sys
-+-import unittest
-+ import getopt
-++import unittest
-+
-+ from email.test import test_email
-+
-Index: misc/Makefile.in
-===================================================================
---- misc/Makefile.in.orig	2006-09-19 23:01:05.000000000 +0200
-+++ misc/Makefile.in	2006-09-19 23:01:08.000000000 +0200
-@@ -94,7 +94,9 @@
- 	for p in $(PACKAGES); \
- 	do \
- 	    gunzip -c $(srcdir)/$$p.tar.gz | (cd $(PKGDIR) ; tar xf -); \
--	    (cd $(PKGDIR)/$$p ; umask 02 ; PYTHONPATH=$(PYTHONLIBDIR) $(PYTHON) $(SETUPCMD)); \
-+	    (cd $(PKGDIR)/$$p ; umask 02 ; \
-+	     if [ "$$p" = "email-2.5.5" ]; then patch -p1 "$(PWD)/CVE-2006-2941.patch"; fi; \
-+	     PYTHONPATH=$(PYTHONLIBDIR) $(PYTHON) $(SETUPCMD)); \
- 	done
- 
- finish:

Copied: trunk/debian/patches/24_CVE-2006-2941.patch (from rev 386, trunk/debian/patches/24_CVE-2006-2941.dpatch)
===================================================================
--- trunk/debian/patches/24_CVE-2006-2941.patch	                        (rev 0)
+++ trunk/debian/patches/24_CVE-2006-2941.patch	2006-09-20 18:51:59 UTC (rev 388)
@@ -0,0 +1,441 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 73_CVE-2006-2941.dpatch by  <lionel at mamane.lu>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: CVE-2006-2941: DoS caused by standards-breaking RFC 2231 formatted headers.
+
+ at DPATCH@
+Index: misc/CVE-2006-2941.patch
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ misc/CVE-2006-2941.patch	2006-09-19 23:02:23.000000000 +0200
+@@ -0,0 +1,414 @@
++diff --recursive -u email-2.5.7/email/__init__.py email-2.5.8/email/__init__.py
++--- email-2.5.7/email/__init__.py	2006-03-06 01:23:54.000000000 +0100
+++++ email-2.5.8/email/__init__.py	2006-07-25 15:10:39.000000000 +0200
++@@ -3,7 +3,7 @@
++
++ """A package for parsing, handling, and generating email messages."""
++
++-__version__ = '2.5.5'
+++__version__ = '2.5.5.debian1'
++
++ __all__ = [
++     'base64MIME',
++diff --recursive -u email-2.5.7/email/_parseaddr.py email-2.5.8/email/_parseaddr.py
++--- email-2.5.7/email/_parseaddr.py	2006-03-06 01:23:54.000000000 +0100
+++++ email-2.5.8/email/_parseaddr.py	2006-06-13 05:43:49.000000000 +0200
++@@ -365,6 +365,7 @@
++                 break
++             elif allowcomments and self.field[self.pos] == '(':
++                 slist.append(self.getcomment())
+++                continue        # have already advanced pos from getcomment
++             elif self.field[self.pos] == '\\':
++                 quote = True
++             else:
++diff --recursive -u email-2.5.7/email/test/test_email.py email-2.5.8/email/test/test_email.py
++--- email-2.5.7/email/test/test_email.py	2006-03-06 01:23:53.000000000 +0100
+++++ email-2.5.8/email/test/test_email.py	2006-07-26 05:58:13.000000000 +0200
++@@ -9,7 +9,7 @@
++ import unittest
++ import warnings
++ from cStringIO import StringIO
++-from types import StringType, ListType
+++from types import StringType, ListType, TupleType
++
++ import email
++
++@@ -2064,6 +2064,12 @@
++            ['foo: ;', '"Jason R. Mastaler" <jason at dom.ain>']),
++            [('', ''), ('Jason R. Mastaler', 'jason at dom.ain')])
++
+++    def test_getaddresses_embedded_comment(self):
+++        """Test proper handling of a nested comment"""
+++        eq = self.assertEqual
+++        addrs = Utils.getaddresses(['User ((nested comment)) <foo at bar.com>'])
+++        eq(addrs[0][1], 'foo at bar.com')
+++
++     def test_utils_quote_unquote(self):
++         eq = self.assertEqual
++         msg = Message()
++@@ -2750,14 +2756,17 @@
++
++ '''
++         msg = email.message_from_string(m)
++-        self.assertEqual(msg.get_param('NAME'),
++-                         (None, None, 'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm'))
+++        param = msg.get_param('NAME')
+++        self.failIf(isinstance(param, TupleType))
+++        self.assertEqual(
+++            param,
+++            'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm')
++
++     def test_rfc2231_no_language_or_charset_in_filename(self):
++         m = '''\
++ Content-Disposition: inline;
++-\tfilename*0="This%20is%20even%20more%20";
++-\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
+++\tfilename*0*="This%20is%20even%20more%20";
+++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
++ \tfilename*2="is it not.pdf"
++
++ '''
++@@ -2768,8 +2777,8 @@
++     def test_rfc2231_no_language_or_charset_in_boundary(self):
++         m = '''\
++ Content-Type: multipart/alternative;
++-\tboundary*0="This%20is%20even%20more%20";
++-\tboundary*1="%2A%2A%2Afun%2A%2A%2A%20";
+++\tboundary*0*="This%20is%20even%20more%20";
+++\tboundary*1*="%2A%2A%2Afun%2A%2A%2A%20";
++ \tboundary*2="is it not.pdf"
++
++ '''
++@@ -2777,12 +2786,38 @@
++         self.assertEqual(msg.get_boundary(),
++                          'This is even more ***fun*** is it not.pdf')
++
+++    def test_rfc2231_partly_encoded(self):
+++        m = '''\
+++Content-Disposition: inline;
+++\tfilename*0="''This%20is%20even%20more%20";
+++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+++\tfilename*2="is it not.pdf"
+++
+++'''
+++        msg = email.message_from_string(m)
+++        self.assertEqual(
+++            msg.get_filename(),
+++            'This%20is%20even%20more%20***fun*** is it not.pdf')
+++
+++    def test_rfc2231_partly_nonencoded(self):
+++        m = '''\
+++Content-Disposition: inline;
+++\tfilename*0="This%20is%20even%20more%20";
+++\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
+++\tfilename*2="is it not.pdf"
+++
+++'''
+++        msg = email.message_from_string(m)
+++        self.assertEqual(
+++            msg.get_filename(),
+++            'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20is it not.pdf')
+++
++     def test_rfc2231_no_language_or_charset_in_charset(self):
++         # This is a nonsensical charset value, but tests the code anyway
++         m = '''\
++ Content-Type: text/plain;
++-\tcharset*0="This%20is%20even%20more%20";
++-\tcharset*1="%2A%2A%2Afun%2A%2A%2A%20";
+++\tcharset*0*="This%20is%20even%20more%20";
+++\tcharset*1*="%2A%2A%2Afun%2A%2A%2A%20";
++ \tcharset*2="is it not.pdf"
++
++ '''
++@@ -2793,8 +2828,8 @@
++     def test_rfc2231_bad_encoding_in_filename(self):
++         m = '''\
++ Content-Disposition: inline;
++-\tfilename*0="bogus'xx'This%20is%20even%20more%20";
++-\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
+++\tfilename*0*="bogus'xx'This%20is%20even%20more%20";
+++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
++ \tfilename*2="is it not.pdf"
++
++ '''
++@@ -2825,9 +2860,9 @@
++     def test_rfc2231_bad_character_in_filename(self):
++         m = '''\
++ Content-Disposition: inline;
++-\tfilename*0="ascii'xx'This%20is%20even%20more%20";
++-\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
++-\tfilename*2="is it not.pdf%E2"
+++\tfilename*0*="ascii'xx'This%20is%20even%20more%20";
+++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+++\tfilename*2*="is it not.pdf%E2"
++
++ '''
++         msg = email.message_from_string(m)
++@@ -2835,6 +2870,102 @@
++                          'This is even more ***fun*** is it not.pdf\xe2')
++
++
+++    def test_rfc2231_unknown_encoding(self):
+++        m = """\
+++Content-Transfer-Encoding: 8bit
+++Content-Disposition: inline; filename*=X-UNKNOWN''myfile.txt
+++
+++"""
+++        msg = email.message_from_string(m)
+++        self.assertEqual(msg.get_filename(), 'myfile.txt')
+++
+++    def test_rfc2231_single_tick_in_filename_extended(self):
+++        eq = self.assertEqual
+++        m = """\
+++Content-Type: application/x-foo;
+++\tname*0*=\"Frank's\"; name*1*=\" Document\"
+++
+++"""
+++        msg = email.message_from_string(m)
+++        charset, language, s = msg.get_param('name')
+++        eq(charset, None)
+++        eq(language, None)
+++        eq(s, "Frank's Document")
+++
+++    def test_rfc2231_single_tick_in_filename(self):
+++        m = """\
+++Content-Type: application/x-foo; name*0=\"Frank's\"; name*1=\" Document\"
+++
+++"""
+++        msg = email.message_from_string(m)
+++        param = msg.get_param('name')
+++        self.failIf(isinstance(param, TupleType))
+++        self.assertEqual(param, "Frank's Document")
+++
+++    def test_rfc2231_tick_attack_extended(self):
+++        eq = self.assertEqual
+++        m = """\
+++Content-Type: application/x-foo;
+++\tname*0*=\"us-ascii'en-us'Frank's\"; name*1*=\" Document\"
+++
+++"""
+++        msg = email.message_from_string(m)
+++        charset, language, s = msg.get_param('name')
+++        eq(charset, 'us-ascii')
+++        eq(language, 'en-us')
+++        eq(s, "Frank's Document")
+++
+++    def test_rfc2231_tick_attack(self):
+++        m = """\
+++Content-Type: application/x-foo;
+++\tname*0=\"us-ascii'en-us'Frank's\"; name*1=\" Document\"
+++
+++"""
+++        msg = email.message_from_string(m)
+++        param = msg.get_param('name')
+++        self.failIf(isinstance(param, TupleType))
+++        self.assertEqual(param, "us-ascii'en-us'Frank's Document")
+++
+++    def test_rfc2231_no_extended_values(self):
+++        eq = self.assertEqual
+++        m = """\
+++Content-Type: application/x-foo; name=\"Frank's Document\"
+++
+++"""
+++        msg = email.message_from_string(m)
+++        eq(msg.get_param('name'), "Frank's Document")
+++
+++    def test_rfc2231_encoded_then_unencoded_segments(self):
+++        eq = self.assertEqual
+++        m = """\
+++Content-Type: application/x-foo;
+++\tname*0*=\"us-ascii'en-us'My\";
+++\tname*1=\" Document\";
+++\tname*2*=\" For You\"
+++
+++"""
+++        msg = email.message_from_string(m)
+++        charset, language, s = msg.get_param('name')
+++        eq(charset, 'us-ascii')
+++        eq(language, 'en-us')
+++        eq(s, 'My Document For You')
+++
+++    def test_rfc2231_unencoded_then_encoded_segments(self):
+++        eq = self.assertEqual
+++        m = """\
+++Content-Type: application/x-foo;
+++\tname*0=\"us-ascii'en-us'My\";
+++\tname*1*=\" Document\";
+++\tname*2*=\" For You\"
+++
+++"""
+++        msg = email.message_from_string(m)
+++        charset, language, s = msg.get_param('name')
+++        eq(charset, 'us-ascii')
+++        eq(language, 'en-us')
+++        eq(s, 'My Document For You')
+++
+++
++ 
++ def _testclasses():
++     mod = sys.modules[__name__]
++diff --recursive -u email-2.5.7/email/Utils.py email-2.5.8/email/Utils.py
++--- email-2.5.7/email/Utils.py	2006-03-06 01:23:54.000000000 +0100
+++++ email-2.5.8/email/Utils.py	2006-07-25 15:10:39.000000000 +0200
++@@ -1,14 +1,15 @@
++-# Copyright (C) 2001,2002 Python Software Foundation
++-# Author: barry at zope.com (Barry Warsaw)
+++# Copyright (C) 2001-2006 Python Software Foundation
+++# Author: Barry Warsaw
+++# Contact: email-sig at python.org
++
++-"""Miscellaneous utilities.
++-"""
+++"""Miscellaneous utilities."""
++
++ import time
++ import socket
++ import re
++ import random
++ import os
+++import urllib
++ import warnings
++ from cStringIO import StringIO
++ from types import ListType
++@@ -53,6 +54,7 @@
++ EMPTYSTRING = ''
++ UEMPTYSTRING = u''
++ CRLF = '\r\n'
+++TICK = "'"
++
++ specialsre = re.compile(r'[][\\()<>@,:;".]')
++ escapesre = re.compile(r'[][\\()"]')
++@@ -277,12 +279,14 @@
++ # RFC2231-related functions - parameter encoding and decoding
++ def decode_rfc2231(s):
++     """Decode string according to RFC 2231"""
++-    import urllib
++-    parts = s.split("'", 2)
++-    if len(parts) == 1:
+++    parts = s.split(TICK, 2)
+++    if len(parts) <= 2:
++         return None, None, urllib.unquote(s)
++-    charset, language, s = parts
++-    return charset, language, urllib.unquote(s)
+++    if len(parts) > 3:
+++        charset, language = pars[:2]
+++        s = TICK.join(parts[2:])
+++        return charset, language, s
+++    return parts
++
++
++ def encode_rfc2231(s, charset=None, language=None):
++@@ -306,35 +310,52 @@
++ def decode_params(params):
++     """Decode parameters list according to RFC 2231.
++
++-    params is a sequence of 2-tuples containing (content type, string value).
+++    params is a sequence of 2-tuples containing (param name, string value).
++     """
+++    # Copy params so we don't mess with the original
+++    params = params[:]
++     new_params = []
++-    # maps parameter's name to a list of continuations
+++    # Map parameter's name to a list of continuations.  The values are a
+++    # 3-tuple of the continuation number, the string value, and a flag
+++    # specifying whether a particular segment is %-encoded.
++     rfc2231_params = {}
++-    # params is a sequence of 2-tuples containing (content_type, string value)
++-    name, value = params[0]
+++    name, value = params.pop(0)
++     new_params.append((name, value))
++-    # Cycle through each of the rest of the parameters.
++-    for name, value in params[1:]:
+++    while params:
+++        name, value = params.pop(0)
+++        if name.endswith('*'):
+++            encoded = True
+++        else:
+++            encoded = False
++         value = unquote(value)
++         mo = rfc2231_continuation.match(name)
++         if mo:
++             name, num = mo.group('name', 'num')
++             if num is not None:
++                 num = int(num)
++-            rfc2231_param1 = rfc2231_params.setdefault(name, [])
++-            rfc2231_param1.append((num, value))
+++            rfc2231_params.setdefault(name, []).append((num, value, encoded))
++         else:
++             new_params.append((name, '"%s"' % quote(value)))
++     if rfc2231_params:
++         for name, continuations in rfc2231_params.items():
++             value = []
+++            extended = False
++             # Sort by number
++             continuations.sort()
++-            # And now append all values in num order
++-            for num, continuation in continuations:
++-                value.append(continuation)
++-            charset, language, value = decode_rfc2231(EMPTYSTRING.join(value))
++-            new_params.append(
++-                (name, (charset, language, '"%s"' % quote(value))))
+++            # And now append all values in numerical order, converting
+++            # %-encodings for the encoded segments.  If any of the
+++            # continuation names ends in a *, then the entire string, after
+++            # decoding segments and concatenating, must have the charset and
+++            # language specifiers at the beginning of the string.
+++            for num, s, encoded in continuations:
+++                if encoded:
+++                    s = urllib.unquote(s)
+++                    extended = True
+++                value.append(s)
+++            value = quote(EMPTYSTRING.join(value))
+++            if extended:
+++                charset, language, value = decode_rfc2231(value)
+++                new_params.append((name, (charset, language, '"%s"' % value)))
+++            else:
+++                new_params.append((name, '"%s"' % value))
++     return new_params
++diff --recursive -u email-2.5.7/PKG-INFO email-2.5.8/PKG-INFO
++--- email-2.5.7/PKG-INFO	2006-03-06 02:39:57.000000000 +0100
+++++ email-2.5.8/PKG-INFO	2006-07-26 06:15:58.000000000 +0200
++@@ -1,10 +1,10 @@
++ Metadata-Version: 1.0
++ Name: email
++-Version: 2.5.5
+++Version: 2.5.5.debian1
++ Summary: Standalone email package
++ Home-page: http://www.python.org/sigs/email-sig
++ Author: Barry Warsaw
++-Author-email: barry at python.org
+++Author-email: email-sig at python.org
++ License: UNKNOWN
++ Description: UNKNOWN
++ Platform: UNKNOWN
++diff --recursive -u email-2.5.7/setup.py email-2.5.8/setup.py
++--- email-2.5.7/setup.py	2006-03-06 01:21:59.000000000 +0100
+++++ email-2.5.8/setup.py	2006-07-25 16:08:43.000000000 +0200
++@@ -1,5 +1,3 @@
++-#! /usr/bin/env python
++-#
++ # Copyright (C) 2001-2006 Python Software Foundation
++
++ # Standard distutils setup.py install script for the `mimelib' library, a next
++@@ -20,7 +18,7 @@
++       version=email.__version__,
++       description='Standalone email package',
++       author='Barry Warsaw',
++-      author_email='barry at python.org',
+++      author_email='email-sig at python.org',
++       url='http://www.python.org/sigs/email-sig',
++       packages=['email'],
++       )
++diff --recursive -u email-2.5.7/testall.py email-2.5.8/testall.py
++--- email-2.5.7/testall.py	2006-03-06 01:21:59.000000000 +0100
+++++ email-2.5.8/testall.py	2006-07-25 16:09:00.000000000 +0200
++@@ -13,8 +13,8 @@
++ """
++
++ import sys
++-import unittest
++ import getopt
+++import unittest
++
++ from email.test import test_email
++
+Index: misc/Makefile.in
+===================================================================
+--- misc/Makefile.in.orig	2006-09-19 23:01:05.000000000 +0200
++++ misc/Makefile.in	2006-09-19 23:01:08.000000000 +0200
+@@ -94,7 +94,9 @@
+ 	for p in $(PACKAGES); \
+ 	do \
+ 	    gunzip -c $(srcdir)/$$p.tar.gz | (cd $(PKGDIR) ; tar xf -); \
+-	    (cd $(PKGDIR)/$$p ; umask 02 ; PYTHONPATH=$(PYTHONLIBDIR) $(PYTHON) $(SETUPCMD)); \
++	    (cd $(PKGDIR)/$$p ; umask 02 ; \
++	     if [ "$$p" = "email-2.5.5" ]; then patch -p1 "$(PWD)/CVE-2006-2941.patch"; fi; \
++	     PYTHONPATH=$(PYTHONLIBDIR) $(PYTHON) $(SETUPCMD)); \
+ 	done
+ 
+ finish:

Deleted: trunk/debian/patches/25_CVE-2006-4624.dpatch
===================================================================
--- trunk/debian/patches/25_CVE-2006-4624.dpatch	2006-09-20 18:49:40 UTC (rev 387)
+++ trunk/debian/patches/25_CVE-2006-4624.dpatch	2006-09-20 18:51:59 UTC (rev 388)
@@ -1,44 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 74_CVE-2006-4624.dpatch by  <lionel at mamane.lu>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Security: log injection vulnerability
-
- at DPATCH@
-Index: Mailman/Utils.py
-===================================================================
---- Mailman/Utils.py.orig	2006-09-19 22:58:19.000000000 +0200
-+++ Mailman/Utils.py	2006-09-19 23:03:24.000000000 +0200
-@@ -53,6 +53,7 @@
- from Mailman import Errors
- from Mailman import Site
- from Mailman.SafeDict import SafeDict
-+from Mailman.Logging.Syslog import syslog
- 
- try:
-     True, False
-@@ -219,9 +220,16 @@
- 
- 
- 
-+# Patterns which may be used to form malicious path to inject a new
-+# line in the mailman error log. (TK: advisory by Moritz Naumann)
-+CRNLpat = re.compile(r'[^\x21-\x7e]')
-+
- def GetPathPieces(envar='PATH_INFO'):
-     path = os.environ.get(envar)
-     if path:
-+        if CRNLpat.search(path):
-+            path = CRNLpat.split(path)[0]
-+            syslog('error', 'Warning: Possible malformed path attack.')
-         return [p for p in path.split('/') if p]
-     return None
- 
-@@ -541,7 +549,6 @@
-                 text = sdict.interpolate(utemplate)
-         except (TypeError, ValueError), e:
-             # The template is really screwed up
--            from Mailman.Logging.Syslog import syslog
-             syslog('error', 'broken template: %s\n%s', filename, e)
-             pass
-     if raw:

Copied: trunk/debian/patches/25_CVE-2006-4624.patch (from rev 386, trunk/debian/patches/25_CVE-2006-4624.dpatch)
===================================================================
--- trunk/debian/patches/25_CVE-2006-4624.patch	                        (rev 0)
+++ trunk/debian/patches/25_CVE-2006-4624.patch	2006-09-20 18:51:59 UTC (rev 388)
@@ -0,0 +1,44 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 74_CVE-2006-4624.dpatch by  <lionel at mamane.lu>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Security: log injection vulnerability
+
+ at DPATCH@
+Index: Mailman/Utils.py
+===================================================================
+--- Mailman/Utils.py.orig	2006-09-19 22:58:19.000000000 +0200
++++ Mailman/Utils.py	2006-09-19 23:03:24.000000000 +0200
+@@ -53,6 +53,7 @@
+ from Mailman import Errors
+ from Mailman import Site
+ from Mailman.SafeDict import SafeDict
++from Mailman.Logging.Syslog import syslog
+ 
+ try:
+     True, False
+@@ -219,9 +220,16 @@
+ 
+ 
+ 
++# Patterns which may be used to form malicious path to inject a new
++# line in the mailman error log. (TK: advisory by Moritz Naumann)
++CRNLpat = re.compile(r'[^\x21-\x7e]')
++
+ def GetPathPieces(envar='PATH_INFO'):
+     path = os.environ.get(envar)
+     if path:
++        if CRNLpat.search(path):
++            path = CRNLpat.split(path)[0]
++            syslog('error', 'Warning: Possible malformed path attack.')
+         return [p for p in path.split('/') if p]
+     return None
+ 
+@@ -541,7 +549,6 @@
+                 text = sdict.interpolate(utemplate)
+         except (TypeError, ValueError), e:
+             # The template is really screwed up
+-            from Mailman.Logging.Syslog import syslog
+             syslog('error', 'broken template: %s\n%s', filename, e)
+             pass
+     if raw:

Modified: trunk/debian/patches/series
===================================================================
--- trunk/debian/patches/series	2006-09-20 18:49:40 UTC (rev 387)
+++ trunk/debian/patches/series	2006-09-20 18:51:59 UTC (rev 388)
@@ -9,9 +9,9 @@
 16_update_debian.patch -p0
 20_qmail_to_mailman.debian.patch -p0
 21_newlist_help.patch -p0
-23_CVE-2006-3636.dpatch -p0
-24_CVE-2006-2941.dpatch -p0
-25_CVE-2006-4624.dpatch -p0
+23_CVE-2006-3636.patch -p0
+24_CVE-2006-2941.patch -p0
+25_CVE-2006-4624.patch -p0
 30_pipermail_threads.patch -p0
 32_MIME_fixup.patch -p0
 51_nocompile.pyc.patch -p0




More information about the Pkg-mailman-hackers mailing list