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)
