Hello community,

here is the log from the commit of package python-Twisted for openSUSE:Factory 
checked in at 2019-12-11 12:09:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Twisted (Old)
 and      /work/SRC/openSUSE:Factory/.python-Twisted.new.4691 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-Twisted"

Wed Dec 11 12:09:24 2019 rev:37 rq:753855 version:19.10.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Twisted/python-Twisted.changes    
2019-09-23 12:17:25.893806547 +0200
+++ /work/SRC/openSUSE:Factory/.python-Twisted.new.4691/python-Twisted.changes  
2019-12-11 12:10:02.832616129 +0100
@@ -1,0 +2,16 @@
+Wed Dec  4 05:01:47 UTC 2019 - Steve Kowalik <[email protected]>
+
+- Update to 19.10.0:
+  * twisted.trial.successResultOf, twisted.trial.failureResultOf, and 
twisted.trial.assertNoResult accept coroutines as well as Deferreds. (#9006)
+  * Fixed circular import in twisted.trial.reporter, introduced in Twisted 
16.0.0. (#8267)
+  * The POP3 server implemented by twisted.mail.pop3 now accepts passwords 
that contain spaces. (#9100)
+  * Incoming HTTP/2 connections will now not time out if they persist for 
longer than one minute. (#9653)
+  * twisted.conch.ssh.keys now correctly writes the "iqmp" parameter in 
serialized RSA private keys as q^-1 mod p rather than p^-1 mod q. (#9681)
+  * twisted.web.server.Request will now use 
twisted.web.server.Site.getContentFile, if it exists, to get a file into which 
to write request content. If getContentFile is not provided by the site, it 
will fall back to the previous behavior of using io.BytesIO for small requests 
and tempfile.TemporaryFile for large ones. (#9655)
+  * twisted.web.client.FileBodyProducer will now stop producing when the 
Deferred returned by FileBodyProducer.startProducing is cancelled. (#9547)
+  * The HTTP/2 server implementation now enforces TCP flow control on control 
frame messages and times out clients that send invalid data without reading 
responses. This closes CVE-2019-9512 (Ping Flood), CVE-2019-9514 (Reset Flood), 
and CVE-2019-9515 (Settings Flood). Thanks to Jonathan Looney and Piotr Sikora. 
(#9694)
+- Add python-38-xml-namespace.patch to fix dictionary mutation under Python 3.8
+- Add python-38-hmac-digestmod.patch to add digestmod parameter where required
+- Add python-38-no-cgi-parseqs.patch to no longer import parse_qs from cgi
+
+-------------------------------------------------------------------

Old:
----
  Twisted-19.7.0.tar.bz2

New:
----
  Twisted-19.10.0.tar.bz2
  python-38-hmac-digestmod.patch
  python-38-no-cgi-parseqs.patch
  python-38-xml-namespace.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-Twisted.spec ++++++
--- /var/tmp/diff_new_pack.Dhluts/_old  2019-12-11 12:10:06.920614409 +0100
+++ /var/tmp/diff_new_pack.Dhluts/_new  2019-12-11 12:10:06.920614409 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-Twisted
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -20,7 +20,7 @@
 %define oldpython python
 %define modname Twisted
 Name:           python-Twisted
-Version:        19.7.0
+Version:        19.10.0
 Release:        0
 Summary:        An asynchronous networking framework written in Python
 License:        MIT
@@ -30,6 +30,9 @@
 Patch1:         skip_MultiCast.patch
 Patch2:         no-pygtkcompat.patch
 Patch3:         test-mktime-invalid-tm_isdst.patch
+Patch4:         python-38-xml-namespace.patch
+Patch5:         python-38-hmac-digestmod.patch
+Patch6:         python-38-no-cgi-parseqs.patch
 BuildRequires:  %{python_module Automat >= 0.3.0}
 BuildRequires:  %{python_module PyHamcrest >= 1.9.0}
 BuildRequires:  %{python_module appdirs >= 1.4.0}

++++++ Twisted-19.7.0.tar.bz2 -> Twisted-19.10.0.tar.bz2 ++++++
++++ 3260 lines of diff (skipped)

++++++ python-38-hmac-digestmod.patch ++++++
Index: Twisted-19.10.0/src/twisted/cred/credentials.py
===================================================================
--- Twisted-19.10.0.orig/src/twisted/cred/credentials.py
+++ Twisted-19.10.0/src/twisted/cred/credentials.py
@@ -439,7 +439,8 @@ class CramMD5Credentials(object):
 
 
     def checkPassword(self, password):
-        verify = hexlify(hmac.HMAC(password, self.challenge).digest())
+        verify = hexlify(
+            hmac.HMAC(password, self.challenge, digestmod=md5).digest())
         return verify == self.response
 
 
Index: Twisted-19.10.0/src/twisted/cred/test/test_cramauth.py
===================================================================
--- Twisted-19.10.0.orig/src/twisted/cred/test/test_cramauth.py
+++ Twisted-19.10.0/src/twisted/cred/test/test_cramauth.py
@@ -7,6 +7,7 @@ Tests for L{twisted.cred}'s implementati
 
 from __future__ import division, absolute_import
 
+from hashlib import md5
 from hmac import HMAC
 from binascii import hexlify
 
@@ -39,7 +40,7 @@ class CramMD5CredentialsTests(TestCase):
         """
         c = CramMD5Credentials()
         chal = c.getChallenge()
-        c.response = hexlify(HMAC(b'secret', chal).digest())
+        c.response = hexlify(HMAC(b'secret', chal, digestmod=md5).digest())
         self.assertTrue(c.checkPassword(b'secret'))
 
 
@@ -61,7 +62,8 @@ class CramMD5CredentialsTests(TestCase):
         """
         c = CramMD5Credentials()
         chal = c.getChallenge()
-        c.response = hexlify(HMAC(b'thewrongsecret', chal).digest())
+        c.response = hexlify(
+            HMAC(b'thewrongsecret', chal, digestmod=md5).digest())
         self.assertFalse(c.checkPassword(b'secret'))
 
 
@@ -75,7 +77,7 @@ class CramMD5CredentialsTests(TestCase):
         chal = c.getChallenge()
         c.setResponse(b" ".join(
             (b"squirrel",
-             hexlify(HMAC(b'supersecret', chal).digest()))))
+             hexlify(HMAC(b'supersecret', chal, digestmod=md5).digest()))))
         self.assertTrue(c.checkPassword(b'supersecret'))
         self.assertEqual(c.username, b"squirrel")
 
Index: Twisted-19.10.0/src/twisted/mail/_cred.py
===================================================================
--- Twisted-19.10.0.orig/src/twisted/mail/_cred.py
+++ Twisted-19.10.0/src/twisted/mail/_cred.py
@@ -7,6 +7,7 @@ Credential managers for L{twisted.mail}.
 
 from __future__ import absolute_import, division
 
+from hashlib import md5
 import hmac
 
 from zope.interface import implementer
@@ -28,7 +29,8 @@ class CramMD5ClientAuthenticator:
 
 
     def challengeResponse(self, secret, chal):
-        response = hmac.HMAC(secret, chal).hexdigest().encode('ascii')
+        response = hmac.HMAC(
+            secret, chal, digestmod=md5).hexdigest().encode('ascii')
         return self.user + b' ' + response
 
 
Index: Twisted-19.10.0/src/twisted/mail/test/test_pop3.py
===================================================================
--- Twisted-19.10.0.orig/src/twisted/mail/test/test_pop3.py
+++ Twisted-19.10.0/src/twisted/mail/test/test_pop3.py
@@ -12,6 +12,7 @@ import base64
 import itertools
 
 from collections import OrderedDict
+from hashlib import md5
 from io import BytesIO
 
 from zope.interface import implementer
@@ -1097,7 +1098,8 @@ class SASLTests(unittest.TestCase):
         p.lineReceived(b"AUTH CRAM-MD5")
         chal = s.getvalue().splitlines()[-1][2:]
         chal = base64.decodestring(chal)
-        response = hmac.HMAC(b'testpassword', chal).hexdigest().encode("ascii")
+        response = hmac.HMAC(
+            b'testpassword', chal, digestmod=md5).hexdigest().encode("ascii")
 
         p.lineReceived(
             base64.encodestring(b'testuser ' + response).rstrip(b'\n'))
++++++ python-38-no-cgi-parseqs.patch ++++++
Index: Twisted-19.10.0/src/twisted/web/test/test_http.py
===================================================================
--- Twisted-19.10.0.orig/src/twisted/web/test/test_http.py
+++ Twisted-19.10.0/src/twisted/web/test/test_http.py
@@ -9,15 +9,14 @@ from __future__ import absolute_import,
 
 import base64
 import calendar
-import cgi
 import random
 
 import hamcrest
 
 try:
-    from urlparse import urlparse, urlunsplit, clear_cache
+    from urlparse import urlparse, urlunsplit, clear_cache, parse_qs
 except ImportError:
-    from urllib.parse import urlparse, urlunsplit, clear_cache
+    from urllib.parse import urlparse, urlunsplit, clear_cache, parse_qs
 
 from io import BytesIO
 from itertools import cycle
@@ -2156,15 +2155,15 @@ Hello,
 class QueryArgumentsTests(unittest.TestCase):
     def testParseqs(self):
         self.assertEqual(
-            cgi.parse_qs(b"a=b&d=c;+=f"),
+            parse_qs(b"a=b&d=c;+=f"),
             http.parse_qs(b"a=b&d=c;+=f"))
         self.assertRaises(
             ValueError, http.parse_qs, b"blah", strict_parsing=True)
         self.assertEqual(
-            cgi.parse_qs(b"a=&b=c", keep_blank_values=1),
+            parse_qs(b"a=&b=c", keep_blank_values=1),
             http.parse_qs(b"a=&b=c", keep_blank_values=1))
         self.assertEqual(
-            cgi.parse_qs(b"a=&b=c"),
+            parse_qs(b"a=&b=c"),
             http.parse_qs(b"a=&b=c"))
 
 
++++++ python-38-xml-namespace.patch ++++++
>From e42ba68b39f0ae98f1ea89a38a9317f2966c7d0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Poisson?= <[email protected]>
Date: Sun, 17 Nov 2019 19:48:53 +0100
Subject: [PATCH] Fix parsing of namespaced attributes with Python 3.8 in
 twisted.words.xish.domish.ExpatElementStream

---
 src/twisted/words/newsfragments/9730.bugfix |  1 +
 src/twisted/words/test/test_domish.py       | 16 ++++++++++++++++
 src/twisted/words/xish/domish.py            | 11 +++++++++--
 3 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 src/twisted/words/newsfragments/9730.bugfix

diff --git a/src/twisted/words/newsfragments/9730.bugfix 
b/src/twisted/words/newsfragments/9730.bugfix
new file mode 100644
index 00000000000..5c91305c8f7
--- /dev/null
+++ b/src/twisted/words/newsfragments/9730.bugfix
@@ -0,0 +1 @@
+Fixed parsing of streams with Python 3.8 when there are spaces in namespaces 
or namespaced attributes in twisted.words.xish.domish.ExpatElementStream
diff --git a/src/twisted/words/test/test_domish.py 
b/src/twisted/words/test/test_domish.py
index a8f8fa76b63..5a691270443 100644
--- a/src/twisted/words/test/test_domish.py
+++ b/src/twisted/words/test/test_domish.py
@@ -350,6 +350,22 @@ def test_namespaceWithWhitespace(self):
             self.elements[0].attributes, {(" bar baz ", "baz"): "quux"})
 
 
+    def test_attributesWithNamespaces(self):
+        """
+        Attributes with namespace are parsed correctly (#9730 regression test).
+        """
+
+        xml = b"""<root xmlns:test='http://example.org' xml:lang='en'>
+                    <test:test>test</test:test>
+                  </root>"""
+
+        # with Python 3.8 and without #9730 fix, the following error would
+        # happen at next line:
+        # ``RuntimeError: dictionary keys changed during iteration``
+        self.stream.parse(xml)
+        self.assertEqual(self.elements[0].uri, "http://example.org";)
+
+
     def testChildPrefix(self):
         xml = b"<root xmlns='testns' xmlns:foo='testns2'><foo:child/></root>"
 
diff --git a/src/twisted/words/xish/domish.py b/src/twisted/words/xish/domish.py
index 2063c410a3c..30e47458f82 100644
--- a/src/twisted/words/xish/domish.py
+++ b/src/twisted/words/xish/domish.py
@@ -807,11 +807,18 @@ def _onStartElement(self, name, attrs):
             qname = ('', name)
 
         # Process attributes
+        new_attrs = {}
+        to_delete = []
         for k, v in attrs.items():
             if " " in k:
                 aqname = k.rsplit(" ", 1)
-                attrs[(aqname[0], aqname[1])] = v
-                del attrs[k]
+                new_attrs[(aqname[0], aqname[1])] = v
+                to_delete.append(k)
+
+        attrs.update(new_attrs)
+
+        for k in to_delete:
+            del attrs[k]
 
         # Construct the new element
         e = Element(qname, self.defaultNsStack[-1], attrs, self.localPrefixes)

Reply via email to