aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/c-ares/src
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2024-12-16 00:09:49 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2024-12-16 00:36:07 +0300
commitd61a51d665801f854d4f2d85ea7c9f0edb6f1608 (patch)
tree032098529c4b4b8fdfbf5389aa9e6affbaf75638 /contrib/libs/c-ares/src
parent0f6fa8ccc1193ad9320c894c564e4915f48501e2 (diff)
downloadydb-d61a51d665801f854d4f2d85ea7c9f0edb6f1608.tar.gz
Update contrib/libs/c-ares to 1.34.4
commit_hash:0ba9edead9220ea805233d858e42e63ba30c021f
Diffstat (limited to 'contrib/libs/c-ares/src')
-rw-r--r--contrib/libs/c-ares/src/lib/ares_config-linux.h3
-rw-r--r--contrib/libs/c-ares/src/lib/ares_private.h17
-rw-r--r--contrib/libs/c-ares/src/lib/ares_set_socket_functions.c4
-rw-r--r--contrib/libs/c-ares/src/lib/ares_socket.c3
-rw-r--r--contrib/libs/c-ares/src/lib/ares_sysconfig.c92
-rw-r--r--contrib/libs/c-ares/src/lib/ares_sysconfig_files.c89
-rw-r--r--contrib/libs/c-ares/src/lib/event/ares_event_configchg.c22
-rw-r--r--contrib/libs/c-ares/src/lib/include/ares_buf.h20
-rw-r--r--contrib/libs/c-ares/src/lib/include/ares_str.h14
-rw-r--r--contrib/libs/c-ares/src/lib/record/ares_dns_multistring.c58
-rw-r--r--contrib/libs/c-ares/src/lib/str/ares_buf.c66
-rw-r--r--contrib/libs/c-ares/src/lib/str/ares_str.c17
12 files changed, 335 insertions, 70 deletions
diff --git a/contrib/libs/c-ares/src/lib/ares_config-linux.h b/contrib/libs/c-ares/src/lib/ares_config-linux.h
index 49e41d4f6e..778bf91eed 100644
--- a/contrib/libs/c-ares/src/lib/ares_config-linux.h
+++ b/contrib/libs/c-ares/src/lib/ares_config-linux.h
@@ -257,6 +257,9 @@
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
+/* Define to 1 if you have the strnlen function. */
+#define HAVE_STRNLEN 1
+
/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */
#define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1
diff --git a/contrib/libs/c-ares/src/lib/ares_private.h b/contrib/libs/c-ares/src/lib/ares_private.h
index ce8c3f2ddc..e6d44e8b86 100644
--- a/contrib/libs/c-ares/src/lib/ares_private.h
+++ b/contrib/libs/c-ares/src/lib/ares_private.h
@@ -388,8 +388,23 @@ ares_status_t ares_sysconfig_set_options(ares_sysconfig_t *sysconfig,
ares_status_t ares_init_by_environment(ares_sysconfig_t *sysconfig);
+
+typedef ares_status_t (*ares_sysconfig_line_cb_t)(const ares_channel_t *channel,
+ ares_sysconfig_t *sysconfig,
+ ares_buf_t *line);
+
+ares_status_t ares_sysconfig_parse_resolv_line(const ares_channel_t *channel,
+ ares_sysconfig_t *sysconfig,
+ ares_buf_t *line);
+
+ares_status_t ares_sysconfig_process_buf(const ares_channel_t *channel,
+ ares_sysconfig_t *sysconfig,
+ ares_buf_t *buf,
+ ares_sysconfig_line_cb_t cb);
+
ares_status_t ares_init_sysconfig_files(const ares_channel_t *channel,
- ares_sysconfig_t *sysconfig);
+ ares_sysconfig_t *sysconfig,
+ ares_bool_t process_resolvconf);
#ifdef __APPLE__
ares_status_t ares_init_sysconfig_macos(const ares_channel_t *channel,
ares_sysconfig_t *sysconfig);
diff --git a/contrib/libs/c-ares/src/lib/ares_set_socket_functions.c b/contrib/libs/c-ares/src/lib/ares_set_socket_functions.c
index 143c491174..7216ffa933 100644
--- a/contrib/libs/c-ares/src/lib/ares_set_socket_functions.c
+++ b/contrib/libs/c-ares/src/lib/ares_set_socket_functions.c
@@ -288,7 +288,9 @@ static int default_asetsockopt(ares_socket_t sock, ares_socket_opt_t opt,
return setsockopt(sock, SOL_SOCKET, SO_RCVBUF, val, val_size);
case ARES_SOCKET_OPT_BIND_DEVICE:
- if (!ares_str_isprint(val, (size_t)val_size)) {
+ /* Count the number of characters before NULL terminator then
+ * validate those are all printable */
+ if (!ares_str_isprint(val, ares_strnlen(val, (size_t)val_size))) {
SET_SOCKERRNO(EINVAL);
return -1;
}
diff --git a/contrib/libs/c-ares/src/lib/ares_socket.c b/contrib/libs/c-ares/src/lib/ares_socket.c
index df02fd61b6..516852a84a 100644
--- a/contrib/libs/c-ares/src/lib/ares_socket.c
+++ b/contrib/libs/c-ares/src/lib/ares_socket.c
@@ -263,7 +263,8 @@ ares_status_t ares_socket_configure(ares_channel_t *channel, int family,
* compatibility */
(void)channel->sock_funcs.asetsockopt(
fd, ARES_SOCKET_OPT_BIND_DEVICE, channel->local_dev_name,
- sizeof(channel->local_dev_name), channel->sock_func_cb_data);
+ (ares_socklen_t)ares_strlen(channel->local_dev_name),
+ channel->sock_func_cb_data);
}
/* Bind to ip address if configured */
diff --git a/contrib/libs/c-ares/src/lib/ares_sysconfig.c b/contrib/libs/c-ares/src/lib/ares_sysconfig.c
index 9f0d7e5061..286db60328 100644
--- a/contrib/libs/c-ares/src/lib/ares_sysconfig.c
+++ b/contrib/libs/c-ares/src/lib/ares_sysconfig.c
@@ -260,6 +260,94 @@ static ares_status_t ares_init_sysconfig_android(const ares_channel_t *channel,
}
#endif
+#if defined(__QNX__)
+static ares_status_t
+ ares_init_sysconfig_qnx(const ares_channel_t *channel,
+ ares_sysconfig_t *sysconfig)
+{
+ /* QNX:
+ * 1. use confstr(_CS_RESOLVE, ...) as primary resolv.conf data, replacing
+ * "_" with " ". If that is empty, then do normal /etc/resolv.conf
+ * processing.
+ * 2. We want to process /etc/nsswitch.conf as normal.
+ * 3. if confstr(_CS_DOMAIN, ...) this is the domain name. Use this as
+ * preference over anything else found.
+ */
+ ares_buf_t *buf = ares_buf_create();
+ unsigned char *data = NULL;
+ size_t data_size = 0;
+ ares_bool_t process_resolvconf = ARES_TRUE;
+ ares_status_t status = ARES_SUCCESS;
+
+ /* Prefer confstr(_CS_RESOLVE, ...) */
+ buf = ares_buf_create();
+ if (buf == NULL) {
+ status = ARES_ENOMEM;
+ goto done;
+ }
+
+ data_size = 1024;
+ data = ares_buf_append_start(buf, &data_size);
+ if (data == NULL) {
+ status = ARES_ENOMEM;
+ goto done;
+ }
+
+ data_size = confstr(_CS_RESOLVE, (char *)data, data_size);
+ if (data_size > 1) {
+ /* confstr returns byte for NULL terminator, strip */
+ data_size--;
+
+ ares_buf_append_finish(buf, data_size);
+ /* Its odd, this uses _ instead of " " between keywords, otherwise the
+ * format is the same as resolv.conf, replace. */
+ ares_buf_replace(buf, (const unsigned char *)"_", 1,
+ (const unsigned char *)" ", 1);
+
+ status = ares_sysconfig_process_buf(channel, sysconfig, buf,
+ ares_sysconfig_parse_resolv_line);
+ if (status != ARES_SUCCESS) {
+ /* ENOMEM is really the only error we'll get here */
+ goto done;
+ }
+
+ /* don't read resolv.conf if we processed *any* nameservers */
+ if (ares_llist_len(sysconfig->sconfig) != 0) {
+ process_resolvconf = ARES_FALSE;
+ }
+ }
+
+ /* Process files */
+ status = ares_init_sysconfig_files(channel, sysconfig, process_resolvconf);
+ if (status != ARES_SUCCESS) {
+ goto done;
+ }
+
+ /* Read confstr(_CS_DOMAIN, ...), but if we had a search path specified with
+ * more than one domain, lets prefer that instead. Its not exactly clear
+ * the best way to handle this. */
+ if (sysconfig->ndomains <= 1) {
+ char domain[256];
+ size_t domain_len;
+
+ domain_len = confstr(_CS_DOMAIN, domain, sizeof(domain_len));
+ if (domain_len != 0) {
+ ares_strsplit_free(sysconfig->domains, sysconfig->ndomains);
+ sysconfig->domains = ares_strsplit(domain, ", ", &sysconfig->ndomains);
+ if (sysconfig->domains == NULL) {
+ status = ARES_ENOMEM;
+ goto done;
+ }
+ }
+ }
+
+done:
+ ares_buf_destroy(buf);
+
+ return status;
+}
+#endif
+
#if defined(CARES_USE_LIBRESOLV)
static ares_status_t
ares_init_sysconfig_libresolv(const ares_channel_t *channel,
@@ -516,8 +604,10 @@ ares_status_t ares_init_by_sysconfig(ares_channel_t *channel)
status = ares_init_sysconfig_macos(channel, &sysconfig);
#elif defined(CARES_USE_LIBRESOLV)
status = ares_init_sysconfig_libresolv(channel, &sysconfig);
+#elif defined(__QNX__)
+ status = ares_init_sysconfig_qnx(channel, &sysconfig);
#else
- status = ares_init_sysconfig_files(channel, &sysconfig);
+ status = ares_init_sysconfig_files(channel, &sysconfig, ARES_TRUE);
#endif
if (status != ARES_SUCCESS) {
diff --git a/contrib/libs/c-ares/src/lib/ares_sysconfig_files.c b/contrib/libs/c-ares/src/lib/ares_sysconfig_files.c
index 49bc330d9d..a6c2a8e62b 100644
--- a/contrib/libs/c-ares/src/lib/ares_sysconfig_files.c
+++ b/contrib/libs/c-ares/src/lib/ares_sysconfig_files.c
@@ -549,9 +549,9 @@ ares_status_t ares_init_by_environment(ares_sysconfig_t *sysconfig)
/* This function will only return ARES_SUCCESS or ARES_ENOMEM. Any other
* conditions are ignored. Users may mess up config files, but we want to
* process anything we can. */
-static ares_status_t parse_resolvconf_line(const ares_channel_t *channel,
- ares_sysconfig_t *sysconfig,
- ares_buf_t *line)
+ares_status_t ares_sysconfig_parse_resolv_line(const ares_channel_t *channel,
+ ares_sysconfig_t *sysconfig,
+ ares_buf_t *line)
{
char option[32];
char value[512];
@@ -726,9 +726,38 @@ done:
return status;
}
-typedef ares_status_t (*line_callback_t)(const ares_channel_t *channel,
- ares_sysconfig_t *sysconfig,
- ares_buf_t *line);
+
+ares_status_t ares_sysconfig_process_buf(const ares_channel_t *channel,
+ ares_sysconfig_t *sysconfig,
+ ares_buf_t *buf,
+ ares_sysconfig_line_cb_t cb)
+{
+ ares_array_t *lines = NULL;
+ size_t num;
+ size_t i;
+ ares_status_t status;
+
+ status = ares_buf_split(buf, (const unsigned char *)"\n", 1,
+ ARES_BUF_SPLIT_TRIM, 0, &lines);
+ if (status != ARES_SUCCESS) {
+ goto done;
+ }
+
+ num = ares_array_len(lines);
+ for (i = 0; i < num; i++) {
+ ares_buf_t **bufptr = ares_array_at(lines, i);
+ ares_buf_t *line = *bufptr;
+
+ status = cb(channel, sysconfig, line);
+ if (status != ARES_SUCCESS) {
+ goto done;
+ }
+ }
+
+done:
+ ares_array_destroy(lines);
+ return status;
+}
/* Should only return:
* ARES_ENOTFOUND - file not found
@@ -737,16 +766,13 @@ typedef ares_status_t (*line_callback_t)(const ares_channel_t *channel,
* ARES_SUCCESS - file processed, doesn't necessarily mean it was a good
* file, but we're not erroring out if we can't parse
* something (or anything at all) */
-static ares_status_t process_config_lines(const ares_channel_t *channel,
- const char *filename,
- ares_sysconfig_t *sysconfig,
- line_callback_t cb)
+static ares_status_t process_config_lines(const ares_channel_t *channel,
+ const char *filename,
+ ares_sysconfig_t *sysconfig,
+ ares_sysconfig_line_cb_t cb)
{
ares_status_t status = ARES_SUCCESS;
- ares_array_t *lines = NULL;
ares_buf_t *buf = NULL;
- size_t num;
- size_t i;
buf = ares_buf_create();
if (buf == NULL) {
@@ -759,43 +785,30 @@ static ares_status_t process_config_lines(const ares_channel_t *channel,
goto done;
}
- status = ares_buf_split(buf, (const unsigned char *)"\n", 1,
- ARES_BUF_SPLIT_TRIM, 0, &lines);
- if (status != ARES_SUCCESS) {
- goto done;
- }
-
- num = ares_array_len(lines);
- for (i = 0; i < num; i++) {
- ares_buf_t **bufptr = ares_array_at(lines, i);
- ares_buf_t *line = *bufptr;
-
- status = cb(channel, sysconfig, line);
- if (status != ARES_SUCCESS) {
- goto done;
- }
- }
+ status = ares_sysconfig_process_buf(channel, sysconfig, buf, cb);
done:
ares_buf_destroy(buf);
- ares_array_destroy(lines);
return status;
}
ares_status_t ares_init_sysconfig_files(const ares_channel_t *channel,
- ares_sysconfig_t *sysconfig)
+ ares_sysconfig_t *sysconfig,
+ ares_bool_t process_resolvconf)
{
ares_status_t status = ARES_SUCCESS;
/* Resolv.conf */
- status = process_config_lines(channel,
- (channel->resolvconf_path != NULL)
- ? channel->resolvconf_path
- : PATH_RESOLV_CONF,
- sysconfig, parse_resolvconf_line);
- if (status != ARES_SUCCESS && status != ARES_ENOTFOUND) {
- goto done;
+ if (process_resolvconf) {
+ status = process_config_lines(channel,
+ (channel->resolvconf_path != NULL)
+ ? channel->resolvconf_path
+ : PATH_RESOLV_CONF,
+ sysconfig, ares_sysconfig_parse_resolv_line);
+ if (status != ARES_SUCCESS && status != ARES_ENOTFOUND) {
+ goto done;
+ }
}
/* Nsswitch.conf */
diff --git a/contrib/libs/c-ares/src/lib/event/ares_event_configchg.c b/contrib/libs/c-ares/src/lib/event/ares_event_configchg.c
index e3e665bd16..5ecc6888ab 100644
--- a/contrib/libs/c-ares/src/lib/event/ares_event_configchg.c
+++ b/contrib/libs/c-ares/src/lib/event/ares_event_configchg.c
@@ -558,14 +558,24 @@ static ares_status_t config_change_check(ares_htable_strvp_t *filestat,
const char *resolvconf_path)
{
size_t i;
- const char *configfiles[5];
+ const char *configfiles[16];
ares_bool_t changed = ARES_FALSE;
+ size_t cnt = 0;
- configfiles[0] = resolvconf_path;
- configfiles[1] = "/etc/nsswitch.conf";
- configfiles[2] = "/etc/netsvc.conf";
- configfiles[3] = "/etc/svc.conf";
- configfiles[4] = NULL;
+ memset(configfiles, 0, sizeof(configfiles));
+
+ configfiles[cnt++] = resolvconf_path;
+ configfiles[cnt++] = "/etc/nsswitch.conf";
+#ifdef _AIX
+ configfiles[cnt++] = "/etc/netsvc.conf";
+#endif
+#ifdef __osf /* Tru64 */
+ configfiles[cnt++] = "/etc/svc.conf";
+#endif
+#ifdef __QNX__
+ configfiles[cnt++] = "/etc/net.cfg";
+#endif
+ configfiles[cnt++] = NULL;
for (i = 0; configfiles[i] != NULL; i++) {
fileinfo_t *fi = ares_htable_strvp_get_direct(filestat, configfiles[i]);
diff --git a/contrib/libs/c-ares/src/lib/include/ares_buf.h b/contrib/libs/c-ares/src/lib/include/ares_buf.h
index 7836a313e0..10d29eaf83 100644
--- a/contrib/libs/c-ares/src/lib/include/ares_buf.h
+++ b/contrib/libs/c-ares/src/lib/include/ares_buf.h
@@ -219,6 +219,26 @@ CARES_EXTERN unsigned char *ares_buf_finish_bin(ares_buf_t *buf, size_t *len);
*/
CARES_EXTERN char *ares_buf_finish_str(ares_buf_t *buf, size_t *len);
+/*! Replace the given search byte sequence with the replacement byte sequence.
+ * This is only valid for allocated buffers, not const buffers. Will replace
+ * all byte sequences starting at the current offset to the end of the buffer.
+ *
+ * \param[in] buf Initialized buffer object. Can not be a "const" buffer.
+ * \param[in] srch Search byte sequence, must not be NULL.
+ * \param[in] srch_size Size of byte sequence, must not be zero.
+ * \param[in] rplc Byte sequence to use as replacement. May be NULL if
+ * rplc_size is zero.
+ * \param[in] rplc_size Size of replacement byte sequence, may be 0.
+ * \return ARES_SUCCESS on success, otherwise on may return failure only on
+ * memory allocation failure or misuse. Will not return indication
+ * if any replacements occurred
+ */
+CARES_EXTERN ares_status_t ares_buf_replace(ares_buf_t *buf,
+ const unsigned char *srch,
+ size_t srch_size,
+ const unsigned char *rplc,
+ size_t rplc_size);
+
/*! Tag a position to save in the buffer in case parsing needs to rollback,
* such as if insufficient data is available, but more data may be added in
* the future. Only a single tag can be set per buffer object. Setting a
diff --git a/contrib/libs/c-ares/src/lib/include/ares_str.h b/contrib/libs/c-ares/src/lib/include/ares_str.h
index ea75b3b3e7..4ee339510b 100644
--- a/contrib/libs/c-ares/src/lib/include/ares_str.h
+++ b/contrib/libs/c-ares/src/lib/include/ares_str.h
@@ -29,6 +29,20 @@
CARES_EXTERN char *ares_strdup(const char *s1);
+/*! Scan up to maxlen bytes for the first NULL character and return
+ * its index, or maxlen if not found. The function only returns
+ * maxlen if the first maxlen bytes were not NULL characters; it
+ * makes no guarantee for what \c str[maxlen] (if defined) is, and
+ * does not access it. It is behaving like the POSIX \c strnlen()
+ * function, except that it returns 0 if the \p str pointer is \c
+ * NULL.
+ *
+ * \param[in] str The string to scan for the NULL character
+ * \param[in] maxlen The maximum number of bytes to scan
+ * \return Index of first NULL byte. Between 0 and maxlen (inclusive).
+ */
+CARES_EXTERN size_t ares_strnlen(const char *str, size_t maxlen);
+
CARES_EXTERN size_t ares_strlen(const char *str);
/*! Copy string from source to destination with destination buffer size
diff --git a/contrib/libs/c-ares/src/lib/record/ares_dns_multistring.c b/contrib/libs/c-ares/src/lib/record/ares_dns_multistring.c
index 57c0d1c0a8..44fcaccd65 100644
--- a/contrib/libs/c-ares/src/lib/record/ares_dns_multistring.c
+++ b/contrib/libs/c-ares/src/lib/record/ares_dns_multistring.c
@@ -146,6 +146,18 @@ ares_status_t ares_dns_multistring_add_own(ares_dns_multistring_t *strs,
return status;
}
+ /* Issue #921, ares_dns_multistring_get() doesn't have a way to indicate
+ * success or fail on a zero-length string which is actually valid. So we
+ * are going to allocate a 1-byte buffer to use as a placeholder in this
+ * case */
+ if (str == NULL) {
+ str = ares_malloc_zero(1);
+ if (str == NULL) {
+ ares_array_remove_last(strs->strs);
+ return ARES_ENOMEM;
+ }
+ }
+
data->data = str;
data->len = len;
@@ -252,36 +264,38 @@ ares_status_t ares_dns_multistring_parse_buf(ares_buf_t *buf,
break; /* LCOV_EXCL_LINE: DefensiveCoding */
}
- if (len) {
- /* When used by the _str() parser, it really needs to be validated to
- * be a valid printable ascii string. Do that here */
- if (validate_printable && ares_buf_len(buf) >= len) {
- size_t mylen;
- const char *data = (const char *)ares_buf_peek(buf, &mylen);
- if (!ares_str_isprint(data, len)) {
- status = ARES_EBADSTR;
- break;
- }
+
+ /* When used by the _str() parser, it really needs to be validated to
+ * be a valid printable ascii string. Do that here */
+ if (len && validate_printable && ares_buf_len(buf) >= len) {
+ size_t mylen;
+ const char *data = (const char *)ares_buf_peek(buf, &mylen);
+ if (!ares_str_isprint(data, len)) {
+ status = ARES_EBADSTR;
+ break;
}
+ }
- if (strs != NULL) {
- unsigned char *data = NULL;
+ if (strs != NULL) {
+ unsigned char *data = NULL;
+ if (len) {
status = ares_buf_fetch_bytes_dup(buf, len, ARES_TRUE, &data);
if (status != ARES_SUCCESS) {
break;
}
- status = ares_dns_multistring_add_own(*strs, data, len);
- if (status != ARES_SUCCESS) {
- ares_free(data);
- break;
- }
- } else {
- status = ares_buf_consume(buf, len);
- if (status != ARES_SUCCESS) {
- break;
- }
+ }
+ status = ares_dns_multistring_add_own(*strs, data, len);
+ if (status != ARES_SUCCESS) {
+ ares_free(data);
+ break;
+ }
+ } else {
+ status = ares_buf_consume(buf, len);
+ if (status != ARES_SUCCESS) {
+ break;
}
}
+
}
if (status != ARES_SUCCESS && strs != NULL) {
diff --git a/contrib/libs/c-ares/src/lib/str/ares_buf.c b/contrib/libs/c-ares/src/lib/str/ares_buf.c
index 69e6b38aac..63acc6cf77 100644
--- a/contrib/libs/c-ares/src/lib/str/ares_buf.c
+++ b/contrib/libs/c-ares/src/lib/str/ares_buf.c
@@ -1104,6 +1104,72 @@ const unsigned char *ares_buf_peek(const ares_buf_t *buf, size_t *len)
return ares_buf_fetch(buf, len);
}
+ares_status_t ares_buf_replace(ares_buf_t *buf, const unsigned char *srch,
+ size_t srch_size, const unsigned char *rplc,
+ size_t rplc_size)
+{
+ size_t processed_len = 0;
+ ares_status_t status;
+
+ if (buf->alloc_buf == NULL || srch == NULL || srch_size == 0 ||
+ (rplc == NULL && rplc_size != 0)) {
+ return ARES_EFORMERR;
+ }
+
+ while (1) {
+ unsigned char *ptr = buf->alloc_buf + buf->offset + processed_len;
+ size_t remaining_len = buf->data_len - buf->offset - processed_len;
+ size_t found_offset = 0;
+ size_t move_data_len;
+
+ /* Find pattern */
+ ptr = ares_memmem(ptr, remaining_len, srch, srch_size);
+ if (ptr == NULL) {
+ break;
+ }
+
+ /* Store the offset this was found because our actual pointer might be
+ * switched out from under us by the call to ensure_space() if the
+ * replacement pattern is larger than the search pattern */
+ found_offset = (size_t)(ptr - (size_t)(buf->alloc_buf + buf->offset));
+ if (rplc_size > srch_size) {
+ status = ares_buf_ensure_space(buf, rplc_size - srch_size);
+ if (status != ARES_SUCCESS) {
+ return status;
+ }
+ }
+
+ /* Impossible, but silence clang */
+ if (buf->alloc_buf == NULL) {
+ return ARES_ENOMEM;
+ }
+
+ /* Recalculate actual pointer */
+ ptr = buf->alloc_buf + buf->offset + found_offset;
+
+ /* Move the data */
+ move_data_len = buf->data_len - buf->offset - found_offset - srch_size;
+ memmove(ptr + rplc_size,
+ ptr + srch_size,
+ move_data_len);
+
+ /* Copy in the replacement data */
+ if (rplc != NULL && rplc_size > 0) {
+ memcpy(ptr, rplc, rplc_size);
+ }
+
+ if (rplc_size > srch_size) {
+ buf->data_len += rplc_size - srch_size;
+ } else {
+ buf->data_len -= srch_size - rplc_size;
+ }
+
+ processed_len = found_offset + rplc_size;
+ }
+
+ return ARES_SUCCESS;
+}
+
ares_status_t ares_buf_peek_byte(const ares_buf_t *buf, unsigned char *b)
{
size_t remaining_len = 0;
diff --git a/contrib/libs/c-ares/src/lib/str/ares_str.c b/contrib/libs/c-ares/src/lib/str/ares_str.c
index f6bfabf11f..0eda1ab9f1 100644
--- a/contrib/libs/c-ares/src/lib/str/ares_str.c
+++ b/contrib/libs/c-ares/src/lib/str/ares_str.c
@@ -32,6 +32,23 @@
# include <stdint.h>
#endif
+size_t ares_strnlen(const char *str, size_t maxlen) {
+ const char *p = NULL;
+ if (str == NULL) {
+ return 0;
+ }
+#ifdef HAVE_STRNLEN
+ (void)p;
+ return strnlen(str, maxlen);
+#else
+ if ((p = memchr(str, 0, maxlen)) == NULL) {
+ return maxlen;
+ } else {
+ return (size_t)(p - str);
+ }
+#endif /* HAVE_STRNLEN */
+}
+
size_t ares_strlen(const char *str)
{
if (str == NULL) {