mirror of
https://github.com/python/cpython.git
synced 2025-10-23 07:02:24 +00:00
Issue #22127: Bypass IDNA for pure-ASCII host names (in particular for numeric IPs).
This commit is contained in:
parent
a73cb8a6b8
commit
eb1c28a849
2 changed files with 78 additions and 10 deletions
|
@ -671,6 +671,9 @@ Library
|
||||||
Extension Modules
|
Extension Modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #22127: Bypass IDNA for pure-ASCII host names
|
||||||
|
(in particular for numeric IPs).
|
||||||
|
|
||||||
- Issue #21407: _decimal: The module now supports function signatures.
|
- Issue #21407: _decimal: The module now supports function signatures.
|
||||||
|
|
||||||
- Issue #21276: posixmodule: Don't define USE_XATTRS on KFreeBSD and the Hurd.
|
- Issue #21276: posixmodule: Don't define USE_XATTRS on KFreeBSD and the Hurd.
|
||||||
|
|
|
@ -1213,6 +1213,71 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper for getsockaddrarg: bypass IDNA for ASCII-only host names
|
||||||
|
(in particular, numeric IP addresses). */
|
||||||
|
struct maybe_idna {
|
||||||
|
PyObject *obj;
|
||||||
|
char *buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
idna_cleanup(struct maybe_idna *data)
|
||||||
|
{
|
||||||
|
Py_CLEAR(data->obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
idna_converter(PyObject *obj, struct maybe_idna *data)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
PyObject *obj2, *obj3;
|
||||||
|
if (obj == NULL) {
|
||||||
|
idna_cleanup(data);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
data->obj = NULL;
|
||||||
|
len = -1;
|
||||||
|
if (PyBytes_Check(obj)) {
|
||||||
|
data->buf = PyBytes_AsString(obj);
|
||||||
|
len = PyBytes_Size(obj);
|
||||||
|
}
|
||||||
|
else if (PyByteArray_Check(obj)) {
|
||||||
|
data->buf = PyByteArray_AsString(obj);
|
||||||
|
len = PyByteArray_Size(obj);
|
||||||
|
}
|
||||||
|
else if (PyUnicode_Check(obj) && PyUnicode_READY(obj) == 0 && PyUnicode_IS_COMPACT_ASCII(obj)) {
|
||||||
|
data->buf = PyUnicode_DATA(obj);
|
||||||
|
len = PyUnicode_GET_LENGTH(obj);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
obj2 = PyUnicode_FromObject(obj);
|
||||||
|
if (!obj2) {
|
||||||
|
PyErr_Format(PyExc_TypeError, "string or unicode text buffer expected, not %s",
|
||||||
|
obj->ob_type->tp_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
obj3 = PyUnicode_AsEncodedString(obj2, "idna", NULL);
|
||||||
|
Py_DECREF(obj2);
|
||||||
|
if (!obj3) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "encoding of hostname failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!PyBytes_Check(obj3)) {
|
||||||
|
Py_DECREF(obj2);
|
||||||
|
PyErr_SetString(PyExc_TypeError, "encoding of hostname failed to return bytes");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
data->obj = obj3;
|
||||||
|
data->buf = PyBytes_AS_STRING(obj3);
|
||||||
|
len = PyBytes_GET_SIZE(obj3);
|
||||||
|
}
|
||||||
|
if (strlen(data->buf) != len) {
|
||||||
|
Py_CLEAR(data->obj);
|
||||||
|
PyErr_SetString(PyExc_TypeError, "host name must not contain NUL character");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return Py_CLEANUP_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a socket address argument according to the socket object's
|
/* Parse a socket address argument according to the socket object's
|
||||||
address family. Return 1 if the address was in the proper format,
|
address family. Return 1 if the address was in the proper format,
|
||||||
|
@ -1307,7 +1372,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
{
|
{
|
||||||
struct sockaddr_in* addr;
|
struct sockaddr_in* addr;
|
||||||
char *host;
|
struct maybe_idna host = {NULL, NULL};
|
||||||
int port, result;
|
int port, result;
|
||||||
if (!PyTuple_Check(args)) {
|
if (!PyTuple_Check(args)) {
|
||||||
PyErr_Format(
|
PyErr_Format(
|
||||||
|
@ -1317,13 +1382,13 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
|
||||||
Py_TYPE(args)->tp_name);
|
Py_TYPE(args)->tp_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!PyArg_ParseTuple(args, "eti:getsockaddrarg",
|
if (!PyArg_ParseTuple(args, "O&i:getsockaddrarg",
|
||||||
"idna", &host, &port))
|
idna_converter, &host, &port))
|
||||||
return 0;
|
return 0;
|
||||||
addr=(struct sockaddr_in*)addr_ret;
|
addr=(struct sockaddr_in*)addr_ret;
|
||||||
result = setipaddr(host, (struct sockaddr *)addr,
|
result = setipaddr(host.buf, (struct sockaddr *)addr,
|
||||||
sizeof(*addr), AF_INET);
|
sizeof(*addr), AF_INET);
|
||||||
PyMem_Free(host);
|
idna_cleanup(&host);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (port < 0 || port > 0xffff) {
|
if (port < 0 || port > 0xffff) {
|
||||||
|
@ -1342,7 +1407,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
{
|
{
|
||||||
struct sockaddr_in6* addr;
|
struct sockaddr_in6* addr;
|
||||||
char *host;
|
struct maybe_idna host = {NULL, NULL};
|
||||||
int port, result;
|
int port, result;
|
||||||
unsigned int flowinfo, scope_id;
|
unsigned int flowinfo, scope_id;
|
||||||
flowinfo = scope_id = 0;
|
flowinfo = scope_id = 0;
|
||||||
|
@ -1354,15 +1419,15 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
|
||||||
Py_TYPE(args)->tp_name);
|
Py_TYPE(args)->tp_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!PyArg_ParseTuple(args, "eti|II",
|
if (!PyArg_ParseTuple(args, "O&i|II",
|
||||||
"idna", &host, &port, &flowinfo,
|
idna_converter, &host, &port, &flowinfo,
|
||||||
&scope_id)) {
|
&scope_id)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
addr = (struct sockaddr_in6*)addr_ret;
|
addr = (struct sockaddr_in6*)addr_ret;
|
||||||
result = setipaddr(host, (struct sockaddr *)addr,
|
result = setipaddr(host.buf, (struct sockaddr *)addr,
|
||||||
sizeof(*addr), AF_INET6);
|
sizeof(*addr), AF_INET6);
|
||||||
PyMem_Free(host);
|
idna_cleanup(&host);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (port < 0 || port > 0xffff) {
|
if (port < 0 || port > 0xffff) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue