From 64456b7d86fe69594658ee3a2b07abfcd1022cde Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 13 Nov 2021 21:27:31 -0500 Subject: [PATCH] (bugfix) dns.c: Correct dns_get_record on FreeBSD - Fix #81618 Modify dns_get_record to test for records result based on dns_errno to accommodate modern FreeBSD, for which res_nsearch() does not update h_errno directly. Add new php_dns_errno macro, and have it consult statp->res_h_errno when OS has res_nsearch(). Fixes #81618 --- ext/standard/dns.c | 4 +++- ext/standard/php_dns.h | 3 +++ ext/standard/tests/bug81618.phpt | 12 ++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 ext/standard/tests/bug81618.phpt diff --git a/ext/standard/dns.c b/ext/standard/dns.c index 937c0ef392106..7e64e96d66e2b 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -795,6 +795,7 @@ PHP_FUNCTION(dns_get_record) zend_long type_param = PHP_DNS_ANY; zval *authns = NULL, *addtl = NULL; int type_to_fetch; + int dns_errno; #if defined(HAVE_DNS_SEARCH) struct sockaddr_storage from; uint32_t fromsize = sizeof(from); @@ -940,8 +941,9 @@ PHP_FUNCTION(dns_get_record) n = php_dns_search(handle, hostname, C_IN, type_to_fetch, answer.qb2, sizeof answer); if (n < 0) { + dns_errno = php_dns_errno(handle); php_dns_free_handle(handle); - switch (h_errno) { + switch (dns_errno) { case NO_DATA: case HOST_NOT_FOUND: continue; diff --git a/ext/standard/php_dns.h b/ext/standard/php_dns.h index 2631759ee457b..68651521999e7 100644 --- a/ext/standard/php_dns.h +++ b/ext/standard/php_dns.h @@ -26,6 +26,7 @@ ((int)dns_search(res, dname, class, type, answer, anslen, (struct sockaddr *)&from, &fromsize)) #define php_dns_free_handle(res) \ dns_free(res) +#define php_dns_errno(handle) h_errno #elif defined(HAVE_RES_NSEARCH) #define php_dns_search(res, dname, class, type, answer, anslen) \ @@ -39,11 +40,13 @@ res_nclose(res); \ php_dns_free_res(res) #endif +#define php_dns_errno(handle) handle->res_h_errno #elif defined(HAVE_RES_SEARCH) #define php_dns_search(res, dname, class, type, answer, anslen) \ res_search(dname, class, type, answer, anslen) #define php_dns_free_handle(res) /* noop */ +#define php_dns_errno(handle) h_errno #endif diff --git a/ext/standard/tests/bug81618.phpt b/ext/standard/tests/bug81618.phpt new file mode 100644 index 0000000000000..fbdb29e90eee3 --- /dev/null +++ b/ext/standard/tests/bug81618.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #81618: dns_get_record failure on FreeBSD +--FILE-- + 0); + +?> + +--EXPECT-- +1