Skip to content

Commit 9622dec

Browse files
authored
[3.13] gh-155336: Preserve resolver errors from gethostby*_r() (GH-155337) (GH-155473)
(cherry picked from commit 5181a6e)
1 parent 7465ac1 commit 9622dec

2 files changed

Lines changed: 16 additions & 14 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix error handling in :func:`socket.gethostbyaddr` and
2+
:func:`socket.gethostbyname_ex` when hostname resolution fails.

Modules/socketmodule.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5807,7 +5807,7 @@ sock_decode_hostname(const char *name)
58075807

58085808
static PyObject *
58095809
gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr,
5810-
size_t alen, int af)
5810+
size_t alen, int af, int h_error)
58115811
{
58125812
char **pch;
58135813
PyObject *rtn_tuple = (PyObject *)NULL;
@@ -5818,7 +5818,7 @@ gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr,
58185818

58195819
if (h == NULL) {
58205820
/* Let's get real error message to return */
5821-
set_herror(state, h_errno);
5821+
set_herror(state, h_error);
58225822
return NULL;
58235823
}
58245824

@@ -5954,6 +5954,7 @@ static PyObject *
59545954
socket_gethostbyname_ex(PyObject *self, PyObject *args)
59555955
{
59565956
char *name;
5957+
int h_error;
59575958
struct hostent *h;
59585959
sock_addr_t addr;
59595960
struct sockaddr *sa;
@@ -5965,7 +5966,6 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
59655966
#else
59665967
char buf[16384];
59675968
int buf_len = (sizeof buf) - 1;
5968-
int errnop;
59695969
#endif
59705970
#ifdef HAVE_GETHOSTBYNAME_R_3_ARG
59715971
int result;
@@ -5984,21 +5984,22 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
59845984
Py_BEGIN_ALLOW_THREADS
59855985
#ifdef HAVE_GETHOSTBYNAME_R
59865986
#if defined(HAVE_GETHOSTBYNAME_R_6_ARG)
5987-
gethostbyname_r(name, &hp_allocated, buf, buf_len,
5988-
&h, &errnop);
5987+
gethostbyname_r(name, &hp_allocated, buf, buf_len, &h, &h_error);
59895988
#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
5990-
h = gethostbyname_r(name, &hp_allocated, buf, buf_len, &errnop);
5989+
h = gethostbyname_r(name, &hp_allocated, buf, buf_len, &h_error);
59915990
#else /* HAVE_GETHOSTBYNAME_R_3_ARG */
59925991
memset((void *) &data, '\0', sizeof(data));
59935992
result = gethostbyname_r(name, &hp_allocated, &data);
59945993
h = (result != 0) ? NULL : &hp_allocated;
5994+
h_error = h_errno;
59955995
#endif
59965996
#else /* not HAVE_GETHOSTBYNAME_R */
59975997
#ifdef USE_GETHOSTBYNAME_LOCK
59985998
PyThread_acquire_lock(netdb_lock, 1);
59995999
#endif
60006000
SUPPRESS_DEPRECATED_CALL
60016001
h = gethostbyname(name);
6002+
h_error = h_errno;
60026003
#endif /* HAVE_GETHOSTBYNAME_R */
60036004
Py_END_ALLOW_THREADS
60046005
/* Some C libraries would require addr.__ss_family instead of
@@ -6007,7 +6008,7 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
60076008
access sa_family. */
60086009
sa = SAS2SA(&addr);
60096010
ret = gethost_common(state, h, SAS2SA(&addr), sizeof(addr),
6010-
sa->sa_family);
6011+
sa->sa_family, h_error);
60116012
#ifdef USE_GETHOSTBYNAME_LOCK
60126013
PyThread_release_lock(netdb_lock);
60136014
#endif
@@ -6046,7 +6047,6 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
60466047
to maintain this alignment. */
60476048
char buf[16384] Py_ALIGNED(8);
60486049
int buf_len = (sizeof buf) - 1;
6049-
int errnop;
60506050
#endif
60516051
#ifdef HAVE_GETHOSTBYNAME_R_3_ARG
60526052
int result;
@@ -6055,6 +6055,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
60556055
const char *ap;
60566056
int al;
60576057
int af;
6058+
int h_error;
60586059

60596060
if (!PyArg_ParseTuple(args, "et:gethostbyaddr", "idna", &ip_num))
60606061
return NULL;
@@ -6087,26 +6088,25 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
60876088
Py_BEGIN_ALLOW_THREADS
60886089
#ifdef HAVE_GETHOSTBYNAME_R
60896090
#if defined(HAVE_GETHOSTBYNAME_R_6_ARG)
6090-
gethostbyaddr_r(ap, al, af,
6091-
&hp_allocated, buf, buf_len,
6092-
&h, &errnop);
6091+
gethostbyaddr_r(ap, al, af, &hp_allocated, buf, buf_len, &h, &h_error);
60936092
#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
6094-
h = gethostbyaddr_r(ap, al, af,
6095-
&hp_allocated, buf, buf_len, &errnop);
6093+
h = gethostbyaddr_r(ap, al, af, &hp_allocated, buf, buf_len, &h_error);
60966094
#else /* HAVE_GETHOSTBYNAME_R_3_ARG */
60976095
memset((void *) &data, '\0', sizeof(data));
60986096
result = gethostbyaddr_r(ap, al, af, &hp_allocated, &data);
60996097
h = (result != 0) ? NULL : &hp_allocated;
6098+
h_error = h_errno;
61006099
#endif
61016100
#else /* not HAVE_GETHOSTBYNAME_R */
61026101
#ifdef USE_GETHOSTBYNAME_LOCK
61036102
PyThread_acquire_lock(netdb_lock, 1);
61046103
#endif
61056104
SUPPRESS_DEPRECATED_CALL
61066105
h = gethostbyaddr(ap, al, af);
6106+
h_error = h_errno;
61076107
#endif /* HAVE_GETHOSTBYNAME_R */
61086108
Py_END_ALLOW_THREADS
6109-
ret = gethost_common(state, h, SAS2SA(&addr), sizeof(addr), af);
6109+
ret = gethost_common(state, h, SAS2SA(&addr), sizeof(addr), af, h_error);
61106110
#ifdef USE_GETHOSTBYNAME_LOCK
61116111
PyThread_release_lock(netdb_lock);
61126112
#endif

0 commit comments

Comments
 (0)