File xmlrpc_gzip_33.patch of Package python3.openSUSE_13.1_Update

Index: Python-3.3.5/Doc/library/xmlrpc.client.rst
===================================================================
--- Python-3.3.5.orig/Doc/library/xmlrpc.client.rst	2014-03-09 09:40:05.000000000 +0100
+++ Python-3.3.5/Doc/library/xmlrpc.client.rst	2014-03-27 16:35:39.652012416 +0100
@@ -123,6 +123,15 @@
    :class:`Server` is retained as an alias for :class:`ServerProxy` for backwards
    compatibility.  New code should use :class:`ServerProxy`.
 
+.. data:: MAX_GZIP_DECODE
+
+   The module constant specifies the amount of bytes that are decompressed by
+   :func:`gzip_decode`. The default value is *20 MB*. A value of *-1* disables
+   the protection.
+
+   .. versionadded:: 3.3.4
+      The constant was added to strengthen the module against gzip bomb
+      attacks.
 
 .. seealso::
 
Index: Python-3.3.5/Lib/test/test_xmlrpc.py
===================================================================
--- Python-3.3.5.orig/Lib/test/test_xmlrpc.py	2014-03-09 09:40:20.000000000 +0100
+++ Python-3.3.5/Lib/test/test_xmlrpc.py	2014-03-27 16:37:11.996511684 +0100
@@ -19,6 +19,11 @@
 except ImportError:
     threading = None
 
+try:
+    import gzip
+except ImportError:
+    gzip = None
+
 alist = [{'astring': 'foo@bar.baz.spam',
           'afloat': 7283.43,
           'anint': 2**20,
@@ -219,6 +224,27 @@
         except socket.error:
             self.assertTrue(has_ssl)
 
+    def test_gzip_decode_limit(self):
+        data = b'\0' * xmlrpclib.MAX_GZIP_DECODE
+        encoded = xmlrpclib.gzip_encode(data)
+        decoded = xmlrpclib.gzip_decode(encoded)
+        self.assertEqual(len(decoded), xmlrpclib.MAX_GZIP_DECODE)
+
+        data = b'\0' * (xmlrpclib.MAX_GZIP_DECODE + 1)
+        encoded = xmlrpclib.gzip_encode(data)
+
+        with self.assertRaisesRegexp(ValueError,
+                                     "max gzipped payload length exceeded"):
+            xmlrpclib.gzip_decode(encoded)
+
+        oldmax = xmlrpclib.MAX_GZIP_DECODE
+        try:
+            xmlrpclib.MAX_GZIP_DECODE = -1
+            xmlrpclib.gzip_decode(encoded)
+        finally:
+            xmlrpclib.MAX_GZIP_DECODE = oldmax
+
+
 class HelperTestCase(unittest.TestCase):
     def test_escape(self):
         self.assertEqual(xmlrpclib.escape("a&b"), "a&b")
@@ -845,7 +871,7 @@
             p.pow(6, 8)
         p("close")()
 
-    def test_gsip_response(self):
+    def test_gzip_response(self):
         t = self.Transport()
         p = xmlrpclib.ServerProxy(URL, transport=t)
         old = self.requestHandler.encode_threshold
@@ -1090,11 +1117,8 @@
     xmlrpc_tests.append(SimpleServerTestCase)
     xmlrpc_tests.append(KeepaliveServerTestCase1)
     xmlrpc_tests.append(KeepaliveServerTestCase2)
-    try:
-        import gzip
+    if gzip is not None:
         xmlrpc_tests.append(GzipServerTestCase)
-    except ImportError:
-        pass #gzip not supported in this build
     xmlrpc_tests.append(MultiPathServerTestCase)
     xmlrpc_tests.append(ServerProxyTestCase)
     xmlrpc_tests.append(FailingServerTestCase)
Index: Python-3.3.5/Lib/xmlrpc/client.py
===================================================================
--- Python-3.3.5.orig/Lib/xmlrpc/client.py	2014-03-09 09:40:22.000000000 +0100
+++ Python-3.3.5/Lib/xmlrpc/client.py	2014-03-27 16:35:39.653012421 +0100
@@ -49,6 +49,7 @@
 # 2003-07-12 gp  Correct marshalling of Faults
 # 2003-10-31 mvl Add multicall support
 # 2004-08-20 mvl Bump minimum supported Python version to 2.1
+# 2013-01-20 ch  Add workaround for gzip bomb vulnerability
 #
 # Copyright (c) 1999-2002 by Secret Labs AB.
 # Copyright (c) 1999-2002 by Fredrik Lundh.
@@ -142,6 +143,10 @@
 except ImportError:
     gzip = None #python can be built without zlib/gzip support
 
+# Limit the maximum amount of decoded data that is decompressed. The
+# limit prevents gzip bomb attacks.
+MAX_GZIP_DECODE = 20 * 1024 * 1024 # 20 MB
+
 # --------------------------------------------------------------------
 # Internal stuff
 
@@ -1044,11 +1049,16 @@
     f = BytesIO(data)
     gzf = gzip.GzipFile(mode="rb", fileobj=f)
     try:
-        decoded = gzf.read()
+        if MAX_GZIP_DECODE < 0: # no limit
+            decoded = gzf.read()
+        else:
+            decoded = gzf.read(MAX_GZIP_DECODE + 1)
     except IOError:
         raise ValueError("invalid data")
     f.close()
     gzf.close()
+    if MAX_GZIP_DECODE >= 0 and len(decoded) > MAX_GZIP_DECODE:
+        raise ValueError("max gzipped payload length exceeded")
     return decoded
 
 ##
openSUSE Build Service is sponsored by