Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit c7ced4d

Browse files
author
Anselm Kruis
committed
Merge branch v3.7.6rc1 into 3.7-slp
2 parents e722c82 + bd18254 commit c7ced4d

File tree

68 files changed

+981
-262
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+981
-262
lines changed

Doc/library/array.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ The following data items and methods are also supported:
172172

173173
Deprecated alias for :meth:`frombytes`.
174174

175+
.. deprecated-removed:: 3.2 3.9
176+
175177

176178
.. method:: array.fromunicode(s)
177179

@@ -234,6 +236,8 @@ The following data items and methods are also supported:
234236

235237
Deprecated alias for :meth:`tobytes`.
236238

239+
.. deprecated-removed:: 3.2 3.9
240+
237241

238242
.. method:: array.tounicode()
239243

Doc/library/asyncio-eventloop.rst

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,21 @@ Opening network connections
429429
reuse_address=None, reuse_port=None, \
430430
allow_broadcast=None, sock=None)
431431

432+
.. note::
433+
The parameter *reuse_address* is no longer supported, as using
434+
:py:data:`~sockets.SO_REUSEADDR` poses a significant security concern for
435+
UDP. Explicitly passing ``reuse_address=True`` will raise an exception.
436+
437+
When multiple processes with differing UIDs assign sockets to an
438+
indentical UDP socket address with ``SO_REUSEADDR``, incoming packets can
439+
become randomly distributed among the sockets.
440+
441+
For supported platforms, *reuse_port* can be used as a replacement for
442+
similar functionality. With *reuse_port*,
443+
:py:data:`~sockets.SO_REUSEPORT` is used instead, which specifically
444+
prevents processes with differing UIDs from assigning sockets to the same
445+
socket address.
446+
432447
Create a datagram connection.
433448

434449
The socket family can be either :py:data:`~socket.AF_INET`,
@@ -457,11 +472,6 @@ Opening network connections
457472
resolution. If given, these should all be integers from the
458473
corresponding :mod:`socket` module constants.
459474

460-
* *reuse_address* tells the kernel to reuse a local socket in
461-
``TIME_WAIT`` state, without waiting for its natural timeout to
462-
expire. If not specified will automatically be set to ``True`` on
463-
Unix.
464-
465475
* *reuse_port* tells the kernel to allow this endpoint to be bound to the
466476
same port as other existing endpoints are bound to, so long as they all
467477
set this flag when being created. This option is not supported on Windows
@@ -485,6 +495,10 @@ Opening network connections
485495
The *family*, *proto*, *flags*, *reuse_address*, *reuse_port,
486496
*allow_broadcast*, and *sock* parameters were added.
487497

498+
.. versionchanged:: 3.7.6
499+
The *reuse_address* parameter is no longer supported due to security
500+
concerns.
501+
488502
.. coroutinemethod:: loop.create_unix_connection(protocol_factory, \
489503
path=None, \*, ssl=None, sock=None, \
490504
server_hostname=None, ssl_handshake_timeout=None)

Doc/library/ssl.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,9 @@ SSL sockets also have the following additional methods and attributes:
12471247
The returned dictionary includes additional X509v3 extension items
12481248
such as ``crlDistributionPoints``, ``caIssuers`` and ``OCSP`` URIs.
12491249

1250+
.. versionchanged:: 3.7.6
1251+
IPv6 address strings no longer have a trailing new line.
1252+
12501253
.. method:: SSLSocket.cipher()
12511254

12521255
Returns a three-value tuple containing the name of the cipher being used, the

Include/patchlevel.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
/*--start constants--*/
1919
#define PY_MAJOR_VERSION 3
2020
#define PY_MINOR_VERSION 7
21-
#define PY_MICRO_VERSION 5
22-
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL
23-
#define PY_RELEASE_SERIAL 0
21+
#define PY_MICRO_VERSION 6
22+
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA
23+
#define PY_RELEASE_SERIAL 1
2424

2525
/* Version as a string */
26-
#define PY_VERSION "3.7.5+"
26+
#define PY_VERSION "3.7.6rc1"
2727
/*--end constants--*/
2828

2929
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.

Lib/asyncio/base_events.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@
6161
# Maximum timeout passed to select to avoid OS limitations
6262
MAXIMUM_SELECT_TIMEOUT = 24 * 3600
6363

64+
# Used for deprecation and removal of `loop.create_datagram_endpoint()`'s
65+
# *reuse_address* parameter
66+
_unset = object()
67+
6468

6569
def _format_handle(handle):
6670
cb = handle._callback
@@ -1138,7 +1142,7 @@ async def start_tls(self, transport, protocol, sslcontext, *,
11381142
async def create_datagram_endpoint(self, protocol_factory,
11391143
local_addr=None, remote_addr=None, *,
11401144
family=0, proto=0, flags=0,
1141-
reuse_address=None, reuse_port=None,
1145+
reuse_address=_unset, reuse_port=None,
11421146
allow_broadcast=None, sock=None):
11431147
"""Create datagram connection."""
11441148
if sock is not None:
@@ -1147,7 +1151,7 @@ async def create_datagram_endpoint(self, protocol_factory,
11471151
f'A UDP Socket was expected, got {sock!r}')
11481152
if (local_addr or remote_addr or
11491153
family or proto or flags or
1150-
reuse_address or reuse_port or allow_broadcast):
1154+
reuse_port or allow_broadcast):
11511155
# show the problematic kwargs in exception msg
11521156
opts = dict(local_addr=local_addr, remote_addr=remote_addr,
11531157
family=family, proto=proto, flags=flags,
@@ -1201,8 +1205,18 @@ async def create_datagram_endpoint(self, protocol_factory,
12011205

12021206
exceptions = []
12031207

1204-
if reuse_address is None:
1205-
reuse_address = os.name == 'posix' and sys.platform != 'cygwin'
1208+
# bpo-37228
1209+
if reuse_address is not _unset:
1210+
if reuse_address:
1211+
raise ValueError("Passing `reuse_address=True` is no "
1212+
"longer supported, as the usage of "
1213+
"SO_REUSEPORT in UDP poses a significant "
1214+
"security concern.")
1215+
else:
1216+
warnings.warn("The *reuse_address* parameter has been "
1217+
"deprecated as of 3.7.6 and is scheduled "
1218+
"for removal in 3.11.", DeprecationWarning,
1219+
stacklevel=2)
12061220

12071221
for ((family, proto),
12081222
(local_address, remote_address)) in addr_pairs_info:
@@ -1211,9 +1225,6 @@ async def create_datagram_endpoint(self, protocol_factory,
12111225
try:
12121226
sock = socket.socket(
12131227
family=family, type=socket.SOCK_DGRAM, proto=proto)
1214-
if reuse_address:
1215-
sock.setsockopt(
1216-
socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
12171228
if reuse_port:
12181229
_set_reuseport(sock)
12191230
if allow_broadcast:

Lib/asyncio/selector_events.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ def _test_selector_event(selector, fd, event):
3939
return bool(key.events & event)
4040

4141

42+
def _check_ssl_socket(sock):
43+
if ssl is not None and isinstance(sock, ssl.SSLSocket):
44+
raise TypeError("Socket cannot be of type SSLSocket")
45+
46+
4247
class BaseSelectorEventLoop(base_events.BaseEventLoop):
4348
"""Selector event loop.
4449
@@ -345,6 +350,7 @@ async def sock_recv(self, sock, n):
345350
The maximum amount of data to be received at once is specified by
346351
nbytes.
347352
"""
353+
_check_ssl_socket(sock)
348354
if self._debug and sock.gettimeout() != 0:
349355
raise ValueError("the socket must be non-blocking")
350356
fut = self.create_future()
@@ -378,6 +384,7 @@ async def sock_recv_into(self, sock, buf):
378384
The received data is written into *buf* (a writable buffer).
379385
The return value is the number of bytes written.
380386
"""
387+
_check_ssl_socket(sock)
381388
if self._debug and sock.gettimeout() != 0:
382389
raise ValueError("the socket must be non-blocking")
383390
fut = self.create_future()
@@ -415,6 +422,7 @@ async def sock_sendall(self, sock, data):
415422
raised, and there is no way to determine how much data, if any, was
416423
successfully processed by the receiving end of the connection.
417424
"""
425+
_check_ssl_socket(sock)
418426
if self._debug and sock.gettimeout() != 0:
419427
raise ValueError("the socket must be non-blocking")
420428
fut = self.create_future()
@@ -451,6 +459,7 @@ async def sock_connect(self, sock, address):
451459
452460
This method is a coroutine.
453461
"""
462+
_check_ssl_socket(sock)
454463
if self._debug and sock.gettimeout() != 0:
455464
raise ValueError("the socket must be non-blocking")
456465

@@ -508,6 +517,7 @@ async def sock_accept(self, sock):
508517
object usable to send and receive data on the connection, and address
509518
is the address bound to the socket on the other end of the connection.
510519
"""
520+
_check_ssl_socket(sock)
511521
if self._debug and sock.gettimeout() != 0:
512522
raise ValueError("the socket must be non-blocking")
513523
fut = self.create_future()

0 commit comments

Comments
 (0)