Commit fc0275a1 authored by Martin v. Löwis's avatar Martin v. Löwis

Issue #1027206: Support IDNA in gethostbyname, gethostbyname_ex and

getaddrinfo. Patch by David Watson.
parent d41a37a1
...@@ -637,6 +637,11 @@ class GeneralModuleTests(unittest.TestCase): ...@@ -637,6 +637,11 @@ class GeneralModuleTests(unittest.TestCase):
flags=socket.AI_PASSIVE) flags=socket.AI_PASSIVE)
self.assertEqual(a, b) self.assertEqual(a, b)
def test_idna(self):
# these should all be successful
socket.gethostbyname('испытание.python.org')
socket.gethostbyname_ex('испытание.python.org')
socket.getaddrinfo('испытание.python.org',0)
@unittest.skipUnless(thread, 'Threading required for this test.') @unittest.skipUnless(thread, 'Threading required for this test.')
class BasicTCPTest(SocketConnectedTest): class BasicTCPTest(SocketConnectedTest):
......
...@@ -66,6 +66,8 @@ Core and Builtins ...@@ -66,6 +66,8 @@ Core and Builtins
Extensions Extensions
---------- ----------
- Issue #1027206: Support IDNA in gethostbyname, gethostbyname_ex and getaddrinfo.
- Issue #9214: Set operations on a KeysView or ItemsView in collections - Issue #9214: Set operations on a KeysView or ItemsView in collections
now correctly return a set. (Patch by Eli Bendersky.) now correctly return a set. (Patch by Eli Bendersky.)
......
...@@ -3000,12 +3000,16 @@ socket_gethostbyname(PyObject *self, PyObject *args) ...@@ -3000,12 +3000,16 @@ socket_gethostbyname(PyObject *self, PyObject *args)
{ {
char *name; char *name;
sock_addr_t addrbuf; sock_addr_t addrbuf;
PyObject *ret = NULL;
if (!PyArg_ParseTuple(args, "s:gethostbyname", &name)) if (!PyArg_ParseTuple(args, "et:gethostbyname", "idna", &name))
return NULL; return NULL;
if (setipaddr(name, SAS2SA(&addrbuf), sizeof(addrbuf), AF_INET) < 0) if (setipaddr(name, SAS2SA(&addrbuf), sizeof(addrbuf), AF_INET) < 0)
return NULL; goto finally;
return makeipaddr(SAS2SA(&addrbuf), sizeof(struct sockaddr_in)); ret = makeipaddr(SAS2SA(&addrbuf), sizeof(struct sockaddr_in));
finally:
PyMem_Free(name);
return ret;
} }
PyDoc_STRVAR(gethostbyname_doc, PyDoc_STRVAR(gethostbyname_doc,
...@@ -3156,7 +3160,7 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args) ...@@ -3156,7 +3160,7 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
struct sockaddr_in addr; struct sockaddr_in addr;
#endif #endif
struct sockaddr *sa; struct sockaddr *sa;
PyObject *ret; PyObject *ret = NULL;
#ifdef HAVE_GETHOSTBYNAME_R #ifdef HAVE_GETHOSTBYNAME_R
struct hostent hp_allocated; struct hostent hp_allocated;
#ifdef HAVE_GETHOSTBYNAME_R_3_ARG #ifdef HAVE_GETHOSTBYNAME_R_3_ARG
...@@ -3171,10 +3175,10 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args) ...@@ -3171,10 +3175,10 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
#endif #endif
#endif /* HAVE_GETHOSTBYNAME_R */ #endif /* HAVE_GETHOSTBYNAME_R */
if (!PyArg_ParseTuple(args, "s:gethostbyname_ex", &name)) if (!PyArg_ParseTuple(args, "et:gethostbyname_ex", "idna", &name))
return NULL; return NULL;
if (setipaddr(name, (struct sockaddr *)&addr, sizeof(addr), AF_INET) < 0) if (setipaddr(name, (struct sockaddr *)&addr, sizeof(addr), AF_INET) < 0)
return NULL; goto finally;
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_GETHOSTBYNAME_R #ifdef HAVE_GETHOSTBYNAME_R
#if defined(HAVE_GETHOSTBYNAME_R_6_ARG) #if defined(HAVE_GETHOSTBYNAME_R_6_ARG)
...@@ -3204,6 +3208,8 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args) ...@@ -3204,6 +3208,8 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
#ifdef USE_GETHOSTBYNAME_LOCK #ifdef USE_GETHOSTBYNAME_LOCK
PyThread_release_lock(netdb_lock); PyThread_release_lock(netdb_lock);
#endif #endif
finally:
PyMem_Free(name);
return ret; return ret;
} }
...@@ -3228,7 +3234,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args) ...@@ -3228,7 +3234,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
struct sockaddr *sa = (struct sockaddr *)&addr; struct sockaddr *sa = (struct sockaddr *)&addr;
char *ip_num; char *ip_num;
struct hostent *h; struct hostent *h;
PyObject *ret; PyObject *ret = NULL;
#ifdef HAVE_GETHOSTBYNAME_R #ifdef HAVE_GETHOSTBYNAME_R
struct hostent hp_allocated; struct hostent hp_allocated;
#ifdef HAVE_GETHOSTBYNAME_R_3_ARG #ifdef HAVE_GETHOSTBYNAME_R_3_ARG
...@@ -3250,11 +3256,11 @@ socket_gethostbyaddr(PyObject *self, PyObject *args) ...@@ -3250,11 +3256,11 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
int al; int al;
int af; int af;
if (!PyArg_ParseTuple(args, "s:gethostbyaddr", &ip_num)) if (!PyArg_ParseTuple(args, "et:gethostbyaddr", "idna", &ip_num))
return NULL; return NULL;
af = AF_UNSPEC; af = AF_UNSPEC;
if (setipaddr(ip_num, sa, sizeof(addr), af) < 0) if (setipaddr(ip_num, sa, sizeof(addr), af) < 0)
return NULL; goto finally;
af = sa->sa_family; af = sa->sa_family;
ap = NULL; ap = NULL;
al = 0; al = 0;
...@@ -3271,7 +3277,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args) ...@@ -3271,7 +3277,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
#endif #endif
default: default:
PyErr_SetString(socket_error, "unsupported address family"); PyErr_SetString(socket_error, "unsupported address family");
return NULL; goto finally;
} }
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_GETHOSTBYNAME_R #ifdef HAVE_GETHOSTBYNAME_R
...@@ -3298,6 +3304,8 @@ socket_gethostbyaddr(PyObject *self, PyObject *args) ...@@ -3298,6 +3304,8 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
#ifdef USE_GETHOSTBYNAME_LOCK #ifdef USE_GETHOSTBYNAME_LOCK
PyThread_release_lock(netdb_lock); PyThread_release_lock(netdb_lock);
#endif #endif
finally:
PyMem_Free(ip_num);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment