From 86d1a677fd310d7d90d6f7545c02a4bd68e1d955 Mon Sep 17 00:00:00 2001 From: dartraiden Date: Wed, 4 Jun 2025 09:49:23 +0300 Subject: libcurl: update to 8.14.0 --- libs/libcurl/src/httpsrr.c | 95 +++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 56 deletions(-) (limited to 'libs/libcurl/src/httpsrr.c') diff --git a/libs/libcurl/src/httpsrr.c b/libs/libcurl/src/httpsrr.c index a948361ba4..8111d0fc6e 100644 --- a/libs/libcurl/src/httpsrr.c +++ b/libs/libcurl/src/httpsrr.c @@ -38,76 +38,67 @@ #include "curl_memory.h" #include "memdebug.h" -CURLcode Curl_httpsrr_decode_alpn(const unsigned char *cp, size_t len, - unsigned char *alpns) +#define MAX_ALPN_LENGTH 255 + +static CURLcode httpsrr_decode_alpn(const char *cp, size_t len, + unsigned char *alpns) { /* - * spec here is as per RFC 9460, section-7.1.1 - * encoding is a concatenated list of strings each preceded by a one - * octet length - * output is comma-sep list of the strings - * implementations may or may not handle quoting of comma within - * string values, so we might see a comma within the wire format - * version of a string, in which case we will precede that by a - * backslash - same goes for a backslash character, and of course - * we need to use two backslashes in strings when we mean one;-) + * The wire-format value for "alpn" consists of at least one alpn-id + * prefixed by its length as a single octet, and these length-value pairs + * are concatenated to form the SvcParamValue. These pairs MUST exactly fill + * the SvcParamValue; otherwise, the SvcParamValue is malformed. */ - struct dynbuf dval; int idnum = 0; - Curl_dyn_init(&dval, DYN_DOH_RESPONSE); while(len > 0) { size_t tlen = (size_t) *cp++; - size_t i; enum alpnid id; len--; if(tlen > len) - goto err; - /* add escape char if needed, clunky but easier to read */ - for(i = 0; i != tlen; i++) { - if('\\' == *cp || ',' == *cp) { - if(Curl_dyn_addn(&dval, "\\", 1)) - goto err; - } - if(Curl_dyn_addn(&dval, cp++, 1)) - goto err; - } - len -= tlen; + return CURLE_BAD_CONTENT_ENCODING; /* we only store ALPN ids we know about */ - id = Curl_alpn2alpnid(Curl_dyn_ptr(&dval), Curl_dyn_len(&dval)); + id = Curl_alpn2alpnid(cp, tlen); if(id != ALPN_none) { if(idnum == MAX_HTTPSRR_ALPNS) break; - alpns[idnum++] = (unsigned char)id; + if(idnum && memchr(alpns, id, idnum)) + /* this ALPN id is already stored */ + ; + else + alpns[idnum++] = (unsigned char)id; } - Curl_dyn_reset(&dval); + cp += tlen; + len -= tlen; } - Curl_dyn_free(&dval); if(idnum < MAX_HTTPSRR_ALPNS) alpns[idnum] = ALPN_none; /* terminate the list */ return CURLE_OK; -err: - Curl_dyn_free(&dval); - return CURLE_BAD_CONTENT_ENCODING; } CURLcode Curl_httpsrr_set(struct Curl_easy *data, struct Curl_https_rrinfo *hi, uint16_t rrkey, const uint8_t *val, size_t vlen) { + CURLcode result = CURLE_OK; switch(rrkey) { + case HTTPS_RR_CODE_MANDATORY: + CURL_TRC_DNS(data, "HTTPS RR MANDATORY left to implement"); + break; case HTTPS_RR_CODE_ALPN: /* str_list */ - Curl_httpsrr_decode_alpn(val, vlen, hi->alpns); + result = httpsrr_decode_alpn((const char *)val, vlen, hi->alpns); CURL_TRC_DNS(data, "HTTPS RR ALPN: %u %u %u %u", hi->alpns[0], hi->alpns[1], hi->alpns[2], hi->alpns[3]); break; case HTTPS_RR_CODE_NO_DEF_ALPN: + if(vlen) /* no data */ + return CURLE_BAD_FUNCTION_ARGUMENT; hi->no_def_alpn = TRUE; CURL_TRC_DNS(data, "HTTPS RR no-def-alpn"); break; case HTTPS_RR_CODE_IPV4: /* addr4 list */ - if(!vlen) + if(!vlen || (vlen & 3)) /* the size must be 4-byte aligned */ return CURLE_BAD_FUNCTION_ARGUMENT; hi->ipv4hints = Curl_memdup(val, vlen); if(!hi->ipv4hints) @@ -125,7 +116,7 @@ CURLcode Curl_httpsrr_set(struct Curl_easy *data, CURL_TRC_DNS(data, "HTTPS RR ECH"); break; case HTTPS_RR_CODE_IPV6: /* addr6 list */ - if(!vlen) + if(!vlen || (vlen & 15)) /* the size must be 16-byte aligned */ return CURLE_BAD_FUNCTION_ARGUMENT; hi->ipv6hints = Curl_memdup(val, vlen); if(!hi->ipv6hints) @@ -143,7 +134,7 @@ CURLcode Curl_httpsrr_set(struct Curl_easy *data, CURL_TRC_DNS(data, "HTTPS RR unknown code"); break; } - return CURLE_OK; + return result; } struct Curl_https_rrinfo * @@ -168,31 +159,23 @@ void Curl_httpsrr_cleanup(struct Curl_https_rrinfo *rrinfo) static CURLcode httpsrr_opt(struct Curl_easy *data, const ares_dns_rr_t *rr, - ares_dns_rr_key_t key, size_t idx) + ares_dns_rr_key_t key, size_t idx, + struct Curl_https_rrinfo *hinfo) { - size_t len = 0; const unsigned char *val = NULL; unsigned short code; - struct thread_data *res = &data->state.async.thdata; - struct Curl_https_rrinfo *hi = &res->hinfo; + size_t len = 0; code = ares_dns_rr_get_opt(rr, key, idx, &val, &len); - return Curl_httpsrr_set(data, hi, code, val, len); + return Curl_httpsrr_set(data, hinfo, code, val, len); } -void Curl_dnsrec_done_cb(void *arg, ares_status_t status, - size_t timeouts, - const ares_dns_record_t *dnsrec) +CURLcode Curl_httpsrr_from_ares(struct Curl_easy *data, + const ares_dns_record_t *dnsrec, + struct Curl_https_rrinfo *hinfo) { - struct Curl_easy *data = arg; CURLcode result = CURLE_OK; size_t i; - struct thread_data *res = &data->state.async.thdata; - - res->num_pending--; - (void)timeouts; - if((ARES_SUCCESS != status) || !dnsrec) - return; for(i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) { const char *target; @@ -205,24 +188,24 @@ void Curl_dnsrec_done_cb(void *arg, ares_status_t status, is in ServiceMode */ target = ares_dns_rr_get_str(rr, ARES_RR_HTTPS_TARGET); if(target && target[0]) { - res->hinfo.target = strdup(target); - if(!res->hinfo.target) { + hinfo->target = strdup(target); + if(!hinfo->target) { result = CURLE_OUT_OF_MEMORY; goto out; } - CURL_TRC_DNS(data, "HTTPS RR target: %s", res->hinfo.target); + CURL_TRC_DNS(data, "HTTPS RR target: %s", hinfo->target); } CURL_TRC_DNS(data, "HTTPS RR priority: %u", ares_dns_rr_get_u16(rr, ARES_RR_HTTPS_PRIORITY)); for(opt = 0; opt < ares_dns_rr_get_opt_cnt(rr, ARES_RR_HTTPS_PARAMS); opt++) { - result = httpsrr_opt(data, rr, ARES_RR_HTTPS_PARAMS, opt); + result = httpsrr_opt(data, rr, ARES_RR_HTTPS_PARAMS, opt, hinfo); if(result) break; } } out: - res->result = result; + return result; } #endif /* USE_ARES */ -- cgit v1.2.3