diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index 4e6db15a74f..3941ec18d07 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -120,8 +120,16 @@ Compressing and decompressing data in memory ``9`` (inclusive), optionally OR-ed with the constant :const:`PRESET_EXTREME`. If neither *preset* nor *filters* are given, the default behavior is to use :const:`PRESET_DEFAULT` (preset level ``6``). - Higher presets produce smaller output, but make compression more CPU- and - memory-intensive, and also increase the memory required for decompression. + Higher presets produce smaller output, but make the compression process + slower. + + .. note:: + + In addition to being more CPU-intensive, compression with higher presets + also requires much more memory (and produces output that needs more memory + to decompress). With preset ``9`` for example, the overhead for an + :class:`LZMACompressor` object can be as high as 800MiB. For this reason, + it is generally best to stick with the default preset. The *filters* argument (if provided) should be a filter chain specifier. See :ref:`filter-chain-specs` for details. diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index a7cee599102..b5c16ca5120 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1248,6 +1248,13 @@ class GeneralModuleTests(unittest.TestCase): srv.listen(0) srv.close() + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.') + def test_flowinfo(self): + self.assertRaises(OverflowError, socket.getnameinfo, + ('::1',0, 0xffffffff), 0) + with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as s: + self.assertRaises(OverflowError, s.bind, ('::1', 0, -10)) + @unittest.skipUnless(HAVE_SOCKET_CAN, 'SocketCan required for this test.') class BasicCANTest(unittest.TestCase): diff --git a/Misc/ACKS b/Misc/ACKS index 88b67e014e2..12f4b49d8a3 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -698,6 +698,7 @@ John Nagle Takahiro Nakayama Travers Naran Charles-François Natali +Vilmos Nebehaj Fredrik Nehr Tony Nelson Trent Nelson diff --git a/Misc/NEWS b/Misc/NEWS index ba151e646cc..827aa4e32a9 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1744,6 +1744,9 @@ Tools/Demos Extension Modules ----------------- +- Issue #9975: socket: Fix incorrect use of flowinfo and scope_id. Patch by + Vilmos Nebehaj. + - Issue #7777: socket: Add Reliable Datagram Sockets (PF_RDS) support. - Issue #13159: FileIO and BZ2Compressor/BZ2Decompressor now use a linear-time diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 04ef0dc1b8d..b2ab5e95417 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1095,10 +1095,10 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) PyObject *ret = NULL; if (addrobj) { a = (struct sockaddr_in6 *)addr; - ret = Py_BuildValue("Oiii", + ret = Py_BuildValue("OiII", addrobj, ntohs(a->sin6_port), - a->sin6_flowinfo, + ntohl(a->sin6_flowinfo), a->sin6_scope_id); Py_DECREF(addrobj); } @@ -1386,7 +1386,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, { struct sockaddr_in6* addr; char *host; - int port, flowinfo, scope_id, result; + int port, result; + unsigned int flowinfo, scope_id; flowinfo = scope_id = 0; if (!PyTuple_Check(args)) { PyErr_Format( @@ -1396,7 +1397,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, Py_TYPE(args)->tp_name); return 0; } - if (!PyArg_ParseTuple(args, "eti|ii", + if (!PyArg_ParseTuple(args, "eti|II", "idna", &host, &port, &flowinfo, &scope_id)) { return 0; @@ -1413,9 +1414,15 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, "getsockaddrarg: port must be 0-65535."); return 0; } + if (flowinfo < 0 || flowinfo > 0xfffff) { + PyErr_SetString( + PyExc_OverflowError, + "getsockaddrarg: flowinfo must be 0-1048575."); + return 0; + } addr->sin6_family = s->sock_family; addr->sin6_port = htons((short)port); - addr->sin6_flowinfo = flowinfo; + addr->sin6_flowinfo = htonl(flowinfo); addr->sin6_scope_id = scope_id; *len_ret = sizeof *addr; return 1; @@ -4939,7 +4946,8 @@ socket_getnameinfo(PyObject *self, PyObject *args) PyObject *sa = (PyObject *)NULL; int flags; char *hostp; - int port, flowinfo, scope_id; + int port; + unsigned int flowinfo, scope_id; char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; struct addrinfo hints, *res = NULL; int error; @@ -4953,9 +4961,14 @@ socket_getnameinfo(PyObject *self, PyObject *args) "getnameinfo() argument 1 must be a tuple"); return NULL; } - if (!PyArg_ParseTuple(sa, "si|ii", + if (!PyArg_ParseTuple(sa, "si|II", &hostp, &port, &flowinfo, &scope_id)) return NULL; + if (flowinfo < 0 || flowinfo > 0xfffff) { + PyErr_SetString(PyExc_OverflowError, + "getsockaddrarg: flowinfo must be 0-1048575."); + return NULL; + } PyOS_snprintf(pbuf, sizeof(pbuf), "%d", port); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; @@ -4990,7 +5003,7 @@ socket_getnameinfo(PyObject *self, PyObject *args) { struct sockaddr_in6 *sin6; sin6 = (struct sockaddr_in6 *)res->ai_addr; - sin6->sin6_flowinfo = flowinfo; + sin6->sin6_flowinfo = htonl(flowinfo); sin6->sin6_scope_id = scope_id; break; }