Skip to content

Commit 9f3bdcb

Browse files
segevfinerzooba
authored andcommitted
bpo-23451: Fix socket deprecation warnings in socketmodule.c (#2318)
* bpo-23451: Fix WSASocket and WSADuplicateSocket deprecation warnings * bpo-23451: Add backwards compatibility note about socket share/fromshare * bpo-23451: Fixed `WSAAddressToString`/`WSAStringToAddress` deprecation warnings * bpo-23451: Use `inet_pton`/`inet_ntop` instead of `WSAAddressToString`/`WSAStringToAddress` * bpo-23451: Move `HAVE_INET_PTON` from _socket.vcxproj to pyconfig.h * bpo-23451: Add SUPPRESS_DEPRECATED_CALL to socketmodule.c * bpo-23451: Add a NEWS.d entry * bpo-23451: Corrected NEWS.d entry
1 parent 5b8f972 commit 9f3bdcb

File tree

4 files changed

+24
-171
lines changed

4 files changed

+24
-171
lines changed

Doc/whatsnew/3.7.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,10 @@ Changes in the Python API
451451
* The :attr:`struct.Struct.format` type is now :class:`str` instead of
452452
:class:`bytes`. (Contributed by Victor Stinner in :issue:`21071`.)
453453

454+
* Due to internal changes in :mod:`socket` you won't be able to
455+
:func:`socket.fromshare` a socket :func:`~socket.socket.share`-ed in older
456+
Python versions.
457+
454458

455459
CPython bytecode changes
456460
------------------------
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix socket deprecation warnings in socketmodule.c. Patch by Segev Finer.

Modules/socketmodule.c

Lines changed: 16 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -339,13 +339,6 @@ if_indextoname(index) -- return the corresponding interface name\n\
339339
# include "addrinfo.h"
340340
#endif
341341

342-
#ifndef HAVE_INET_PTON
343-
#if !defined(NTDDI_VERSION) || (NTDDI_VERSION < NTDDI_LONGHORN)
344-
int inet_pton(int af, const char *src, void *dst);
345-
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
346-
#endif
347-
#endif
348-
349342
#ifdef __APPLE__
350343
/* On OS X, getaddrinfo returns no error indication of lookup
351344
failure, so we must use the emulation instead of the libinfo
@@ -514,11 +507,13 @@ select_error(void)
514507
# define SET_SOCK_ERROR(err) WSASetLastError(err)
515508
# define SOCK_TIMEOUT_ERR WSAEWOULDBLOCK
516509
# define SOCK_INPROGRESS_ERR WSAEWOULDBLOCK
510+
# define SUPPRESS_DEPRECATED_CALL __pragma(warning(suppress: 4996))
517511
#else
518512
# define GET_SOCK_ERROR errno
519513
# define SET_SOCK_ERROR(err) do { errno = err; } while (0)
520514
# define SOCK_TIMEOUT_ERR EWOULDBLOCK
521515
# define SOCK_INPROGRESS_ERR EINPROGRESS
516+
# define SUPPRESS_DEPRECATED_CALL
522517
#endif
523518

524519

@@ -4397,15 +4392,15 @@ SIO_LOOPBACK_FAST_PATH: 'option' is a boolean value, and is disabled by default"
43974392
static PyObject*
43984393
sock_share(PySocketSockObject *s, PyObject *arg)
43994394
{
4400-
WSAPROTOCOL_INFO info;
4395+
WSAPROTOCOL_INFOW info;
44014396
DWORD processId;
44024397
int result;
44034398

44044399
if (!PyArg_ParseTuple(arg, "I", &processId))
44054400
return NULL;
44064401

44074402
Py_BEGIN_ALLOW_THREADS
4408-
result = WSADuplicateSocket(s->sock_fd, processId, &info);
4403+
result = WSADuplicateSocketW(s->sock_fd, processId, &info);
44094404
Py_END_ALLOW_THREADS
44104405
if (result == SOCKET_ERROR)
44114406
return set_error();
@@ -4636,7 +4631,7 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds)
46364631
#ifdef MS_WINDOWS
46374632
/* recreate a socket that was duplicated */
46384633
if (PyBytes_Check(fdobj)) {
4639-
WSAPROTOCOL_INFO info;
4634+
WSAPROTOCOL_INFOW info;
46404635
if (PyBytes_GET_SIZE(fdobj) != sizeof(info)) {
46414636
PyErr_Format(PyExc_ValueError,
46424637
"socket descriptor string has wrong size, "
@@ -4645,7 +4640,7 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds)
46454640
}
46464641
memcpy(&info, PyBytes_AS_STRING(fdobj), sizeof(info));
46474642
Py_BEGIN_ALLOW_THREADS
4648-
fd = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
4643+
fd = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
46494644
FROM_PROTOCOL_INFO, &info, 0, WSA_FLAG_OVERLAPPED);
46504645
Py_END_ALLOW_THREADS
46514646
if (fd == INVALID_SOCKET) {
@@ -4678,7 +4673,7 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds)
46784673

46794674
Py_BEGIN_ALLOW_THREADS
46804675
if (support_wsa_no_inherit) {
4681-
fd = WSASocket(family, type, proto,
4676+
fd = WSASocketW(family, type, proto,
46824677
NULL, 0,
46834678
WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
46844679
if (fd == INVALID_SOCKET) {
@@ -5116,6 +5111,7 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
51165111
#ifdef USE_GETHOSTBYNAME_LOCK
51175112
PyThread_acquire_lock(netdb_lock, 1);
51185113
#endif
5114+
SUPPRESS_DEPRECATED_CALL
51195115
h = gethostbyname(name);
51205116
#endif /* HAVE_GETHOSTBYNAME_R */
51215117
Py_END_ALLOW_THREADS
@@ -5214,6 +5210,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
52145210
#ifdef USE_GETHOSTBYNAME_LOCK
52155211
PyThread_acquire_lock(netdb_lock, 1);
52165212
#endif
5213+
SUPPRESS_DEPRECATED_CALL
52175214
h = gethostbyaddr(ap, al, af);
52185215
#endif /* HAVE_GETHOSTBYNAME_R */
52195216
Py_END_ALLOW_THREADS
@@ -5336,18 +5333,18 @@ socket_dup(PyObject *self, PyObject *fdobj)
53365333
SOCKET_T fd, newfd;
53375334
PyObject *newfdobj;
53385335
#ifdef MS_WINDOWS
5339-
WSAPROTOCOL_INFO info;
5336+
WSAPROTOCOL_INFOW info;
53405337
#endif
53415338

53425339
fd = PyLong_AsSocket_t(fdobj);
53435340
if (fd == (SOCKET_T)(-1) && PyErr_Occurred())
53445341
return NULL;
53455342

53465343
#ifdef MS_WINDOWS
5347-
if (WSADuplicateSocket(fd, GetCurrentProcessId(), &info))
5344+
if (WSADuplicateSocketW(fd, GetCurrentProcessId(), &info))
53485345
return set_error();
53495346

5350-
newfd = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
5347+
newfd = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
53515348
FROM_PROTOCOL_INFO,
53525349
&info, 0, WSA_FLAG_OVERLAPPED);
53535350
if (newfd == INVALID_SOCKET)
@@ -5666,6 +5663,7 @@ socket_inet_aton(PyObject *self, PyObject *args)
56665663
packed_addr = INADDR_BROADCAST;
56675664
} else {
56685665

5666+
SUPPRESS_DEPRECATED_CALL
56695667
packed_addr = inet_addr(ip_addr);
56705668

56715669
if (packed_addr == INADDR_NONE) { /* invalid address */
@@ -5709,21 +5707,18 @@ socket_inet_ntoa(PyObject *self, PyObject *args)
57095707
memcpy(&packed_addr, packed_ip.buf, packed_ip.len);
57105708
PyBuffer_Release(&packed_ip);
57115709

5710+
SUPPRESS_DEPRECATED_CALL
57125711
return PyUnicode_FromString(inet_ntoa(packed_addr));
57135712
}
57145713

5715-
#if defined(HAVE_INET_PTON) || defined(MS_WINDOWS)
5714+
#ifdef HAVE_INET_PTON
57165715

57175716
PyDoc_STRVAR(inet_pton_doc,
57185717
"inet_pton(af, ip) -> packed IP address string\n\
57195718
\n\
57205719
Convert an IP address from string format to a packed string suitable\n\
57215720
for use with low-level network functions.");
57225721

5723-
#endif
5724-
5725-
#ifdef HAVE_INET_PTON
5726-
57275722
static PyObject *
57285723
socket_inet_pton(PyObject *self, PyObject *args)
57295724
{
@@ -5768,52 +5763,12 @@ socket_inet_pton(PyObject *self, PyObject *args)
57685763
return NULL;
57695764
}
57705765
}
5771-
#elif defined(MS_WINDOWS)
5772-
5773-
static PyObject *
5774-
socket_inet_pton(PyObject *self, PyObject *args)
5775-
{
5776-
int af;
5777-
char* ip;
5778-
struct sockaddr_in6 addr;
5779-
INT ret, size;
5780-
5781-
if (!PyArg_ParseTuple(args, "is:inet_pton", &af, &ip)) {
5782-
return NULL;
5783-
}
5784-
5785-
size = sizeof(addr);
5786-
ret = WSAStringToAddressA(ip, af, NULL, (LPSOCKADDR)&addr, &size);
5787-
5788-
if (ret) {
5789-
PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
5790-
return NULL;
5791-
} else if(af == AF_INET) {
5792-
struct sockaddr_in *addr4 = (struct sockaddr_in*)&addr;
5793-
return PyBytes_FromStringAndSize((const char *)&(addr4->sin_addr),
5794-
sizeof(addr4->sin_addr));
5795-
} else if (af == AF_INET6) {
5796-
return PyBytes_FromStringAndSize((const char *)&(addr.sin6_addr),
5797-
sizeof(addr.sin6_addr));
5798-
} else {
5799-
PyErr_SetString(PyExc_OSError, "unknown address family");
5800-
return NULL;
5801-
}
5802-
}
5803-
5804-
#endif
5805-
5806-
#if defined(HAVE_INET_PTON) || defined(MS_WINDOWS)
58075766

58085767
PyDoc_STRVAR(inet_ntop_doc,
58095768
"inet_ntop(af, packed_ip) -> string formatted IP address\n\
58105769
\n\
58115770
Convert a packed IP address of the given family to string format.");
58125771

5813-
#endif
5814-
5815-
5816-
#ifdef HAVE_INET_PTON
58175772
static PyObject *
58185773
socket_inet_ntop(PyObject *self, PyObject *args)
58195774
{
@@ -5866,73 +5821,6 @@ socket_inet_ntop(PyObject *self, PyObject *args)
58665821
}
58675822
}
58685823

5869-
#elif defined(MS_WINDOWS)
5870-
5871-
static PyObject *
5872-
socket_inet_ntop(PyObject *self, PyObject *args)
5873-
{
5874-
int af;
5875-
Py_buffer packed_ip;
5876-
struct sockaddr_in6 addr;
5877-
DWORD addrlen, ret, retlen;
5878-
#ifdef ENABLE_IPV6
5879-
char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1];
5880-
#else
5881-
char ip[INET_ADDRSTRLEN + 1];
5882-
#endif
5883-
5884-
/* Guarantee NUL-termination for PyUnicode_FromString() below */
5885-
memset((void *) &ip[0], '\0', sizeof(ip));
5886-
5887-
if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) {
5888-
return NULL;
5889-
}
5890-
5891-
if (af == AF_INET) {
5892-
struct sockaddr_in * addr4 = (struct sockaddr_in *)&addr;
5893-
5894-
if (packed_ip.len != sizeof(struct in_addr)) {
5895-
PyErr_SetString(PyExc_ValueError,
5896-
"invalid length of packed IP address string");
5897-
PyBuffer_Release(&packed_ip);
5898-
return NULL;
5899-
}
5900-
memset(addr4, 0, sizeof(struct sockaddr_in));
5901-
addr4->sin_family = AF_INET;
5902-
memcpy(&(addr4->sin_addr), packed_ip.buf, sizeof(addr4->sin_addr));
5903-
addrlen = sizeof(struct sockaddr_in);
5904-
} else if (af == AF_INET6) {
5905-
if (packed_ip.len != sizeof(struct in6_addr)) {
5906-
PyErr_SetString(PyExc_ValueError,
5907-
"invalid length of packed IP address string");
5908-
PyBuffer_Release(&packed_ip);
5909-
return NULL;
5910-
}
5911-
5912-
memset(&addr, 0, sizeof(addr));
5913-
addr.sin6_family = AF_INET6;
5914-
memcpy(&(addr.sin6_addr), packed_ip.buf, sizeof(addr.sin6_addr));
5915-
addrlen = sizeof(addr);
5916-
} else {
5917-
PyErr_Format(PyExc_ValueError,
5918-
"unknown address family %d", af);
5919-
PyBuffer_Release(&packed_ip);
5920-
return NULL;
5921-
}
5922-
PyBuffer_Release(&packed_ip);
5923-
5924-
retlen = sizeof(ip);
5925-
ret = WSAAddressToStringA((struct sockaddr*)&addr, addrlen, NULL,
5926-
ip, &retlen);
5927-
5928-
if (ret) {
5929-
PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
5930-
return NULL;
5931-
} else {
5932-
return PyUnicode_FromString(ip);
5933-
}
5934-
}
5935-
59365824
#endif /* HAVE_INET_PTON */
59375825

59385826
/* Python interface to getaddrinfo(host, port). */
@@ -6394,7 +6282,7 @@ static PyMethodDef socket_methods[] = {
63946282
METH_VARARGS, inet_aton_doc},
63956283
{"inet_ntoa", socket_inet_ntoa,
63966284
METH_VARARGS, inet_ntoa_doc},
6397-
#if defined(HAVE_INET_PTON) || defined(MS_WINDOWS)
6285+
#ifdef HAVE_INET_PTON
63986286
{"inet_pton", socket_inet_pton,
63996287
METH_VARARGS, inet_pton_doc},
64006288
{"inet_ntop", socket_inet_ntop,
@@ -7713,46 +7601,3 @@ PyInit__socket(void)
77137601
#endif
77147602
return m;
77157603
}
7716-
7717-
7718-
#ifndef HAVE_INET_PTON
7719-
#if !defined(NTDDI_VERSION) || (NTDDI_VERSION < NTDDI_LONGHORN)
7720-
7721-
/* Simplistic emulation code for inet_pton that only works for IPv4 */
7722-
/* These are not exposed because they do not set errno properly */
7723-
7724-
int
7725-
inet_pton(int af, const char *src, void *dst)
7726-
{
7727-
if (af == AF_INET) {
7728-
#if (SIZEOF_INT != 4)
7729-
#error "Not sure if in_addr_t exists and int is not 32-bits."
7730-
#endif
7731-
unsigned int packed_addr;
7732-
packed_addr = inet_addr(src);
7733-
if (packed_addr == INADDR_NONE)
7734-
return 0;
7735-
memcpy(dst, &packed_addr, 4);
7736-
return 1;
7737-
}
7738-
/* Should set errno to EAFNOSUPPORT */
7739-
return -1;
7740-
}
7741-
7742-
const char *
7743-
inet_ntop(int af, const void *src, char *dst, socklen_t size)
7744-
{
7745-
if (af == AF_INET) {
7746-
struct in_addr packed_addr;
7747-
if (size < 16)
7748-
/* Should set errno to ENOSPC. */
7749-
return NULL;
7750-
memcpy(&packed_addr, src, sizeof(packed_addr));
7751-
return strncpy(dst, inet_ntoa(packed_addr), size);
7752-
}
7753-
/* Should set errno to EAFNOSUPPORT */
7754-
return NULL;
7755-
}
7756-
7757-
#endif
7758-
#endif

PC/pyconfig.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,9 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
690690
/* Define to 1 if you have the `erfc' function. */
691691
#define HAVE_ERFC 1
692692

693+
/* Define if you have the 'inet_pton' function. */
694+
#define HAVE_INET_PTON 1
695+
693696
/* framework name */
694697
#define PYTHONFRAMEWORK ""
695698

0 commit comments

Comments
 (0)