From 5b052d4ce3b25c6984af092d4474d5be3d43ec71 Mon Sep 17 00:00:00 2001 From: dartraiden Date: Mon, 20 Feb 2023 21:44:11 +0300 Subject: libcurl: update to 7.88.1 --- libs/libcurl/src/config-win32.h | 7 ----- libs/libcurl/src/connect.c | 18 ++++++++---- libs/libcurl/src/curl_setup.h | 16 +++++++++++ libs/libcurl/src/http.h | 2 +- libs/libcurl/src/http2.c | 23 ++++++++-------- libs/libcurl/src/krb5.c | 2 +- libs/libcurl/src/libcurl.plist | 6 ++-- libs/libcurl/src/setopt.c | 42 +++++++++++++++++++--------- libs/libcurl/src/setup-os400.h | 2 +- libs/libcurl/src/socketpair.c | 61 +++++++++++++++++++++++++++++++++++++---- libs/libcurl/src/socks.c | 4 +-- libs/libcurl/src/transfer.c | 13 +++++---- libs/libcurl/src/url.c | 1 - libs/libcurl/src/urlapi.c | 37 +++++++------------------ libs/libcurl/src/urldata.h | 1 - 15 files changed, 149 insertions(+), 86 deletions(-) (limited to 'libs/libcurl/src') diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h index f014d4746c..17a9a1d048 100644 --- a/libs/libcurl/src/config-win32.h +++ b/libs/libcurl/src/config-win32.h @@ -197,10 +197,6 @@ /* Define if you have the socket function. */ #define HAVE_SOCKET 1 -/* Define if libSSH2 is in use */ -#define USE_LIBSSH2 1 -#define HAVE_LIBSSH2_H 1 - /* Define if you have the strcasecmp function. */ #ifdef __MINGW32__ #define HAVE_STRCASECMP 1 @@ -619,9 +615,6 @@ Vista # define CURL_DISABLE_LDAP 1 #endif -/* if SSL is enabled */ -#define USE_OPENSSL 1 - /* Define to use the Windows crypto library. */ #if !defined(CURL_WINDOWS_APP) #define USE_WIN32_CRYPTO diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c index aa854d9492..e17bf235be 100644 --- a/libs/libcurl/src/connect.c +++ b/libs/libcurl/src/connect.c @@ -186,7 +186,7 @@ addr_first_match(const struct Curl_addrinfo *addr, int family) static const struct Curl_addrinfo * addr_next_match(const struct Curl_addrinfo *addr, int family) { - while(addr->ai_next) { + while(addr && addr->ai_next) { addr = addr->ai_next; if(addr->ai_family == family) return addr; @@ -406,7 +406,8 @@ static CURLcode eyeballer_new(struct eyeballer **pballer, baller->ai_family = ai_family; baller->primary = primary; baller->delay_ms = delay_ms; - baller->timeoutms = (addr && addr->ai_next)? timeout_ms / 2 : timeout_ms; + baller->timeoutms = addr_next_match(baller->addr, baller->ai_family)? + timeout_ms / 2 : timeout_ms; baller->timeout_id = timeout_id; baller->result = CURLE_COULDNT_CONNECT; @@ -467,7 +468,7 @@ static void baller_initiate(struct Curl_cfilter *cf, wcf->sockindex = cf->sockindex; } - if(baller->addr && baller->addr->ai_next) { + if(addr_next_match(baller->addr, baller->ai_family)) { Curl_expire(data, baller->timeoutms, baller->timeout_id); } @@ -498,8 +499,8 @@ static CURLcode baller_start(struct Curl_cfilter *cf, while(baller->addr) { baller->started = Curl_now(); - baller->timeoutms = (baller->addr->ai_next == NULL) ? - timeoutms : timeoutms / 2; + baller->timeoutms = addr_next_match(baller->addr, baller->ai_family) ? + timeoutms / 2 : timeoutms; baller_initiate(cf, data, baller); if(!baller->result) break; @@ -662,7 +663,8 @@ evaluate: DEBUGF(LOG_CF(data, cf, "%s done", baller->name)); } else { - DEBUGF(LOG_CF(data, cf, "%s starting", baller->name)); + DEBUGF(LOG_CF(data, cf, "%s starting (timeout=%ldms)", + baller->name, baller->timeoutms)); ++ongoing; ++added; } @@ -799,6 +801,8 @@ static CURLcode start_connect(struct Curl_cfilter *cf, timeout_ms, EXPIRE_DNS_PER_NAME); if(result) return result; + DEBUGF(LOG_CF(data, cf, "created %s (timeout %ldms)", + ctx->baller[0]->name, ctx->baller[0]->timeoutms)); if(addr1) { /* second one gets a delayed start */ result = eyeballer_new(&ctx->baller[1], ctx->cf_create, addr1, ai_family1, @@ -808,6 +812,8 @@ static CURLcode start_connect(struct Curl_cfilter *cf, timeout_ms, EXPIRE_DNS_PER_NAME2); if(result) return result; + DEBUGF(LOG_CF(data, cf, "created %s (timeout %ldms)", + ctx->baller[1]->name, ctx->baller[1]->timeoutms)); } Curl_expire(data, data->set.happy_eyeballs_timeout, diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h index f0633ddfff..968c8ccbc8 100644 --- a/libs/libcurl/src/curl_setup.h +++ b/libs/libcurl/src/curl_setup.h @@ -61,6 +61,16 @@ # ifndef NOGDI # define NOGDI # endif +/* Detect Windows App environment which has a restricted access + * to the Win32 APIs. */ +# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \ + defined(WINAPI_FAMILY) +# include +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ + !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define CURL_WINDOWS_APP +# endif +# endif #endif /* @@ -852,4 +862,10 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, # endif #endif +/* OpenSSLv3 marks DES, MD5 and ENGINE functions deprecated but we have no + replacements (yet) so tell the compiler to not warn for them. */ +#ifdef USE_OPENSSL +#define OPENSSL_SUPPRESS_DEPRECATED +#endif + #endif /* HEADER_CURL_SETUP_H */ diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h index 115db9b79b..a74844cc01 100644 --- a/libs/libcurl/src/http.h +++ b/libs/libcurl/src/http.h @@ -42,7 +42,7 @@ typedef enum { #ifndef CURL_DISABLE_HTTP -#if defined(_WIN32) && (defined(ENABLE_QUIC) || defined(USE_NGHTTP2)) +#if defined(ENABLE_QUIC) || defined(USE_NGHTTP2) #include #endif diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c index c2da6b2af9..8d72977e59 100644 --- a/libs/libcurl/src/http2.c +++ b/libs/libcurl/src/http2.c @@ -467,6 +467,7 @@ static CURLcode flush_output(struct Curl_cfilter *cf, } if((size_t)written < buflen) { Curl_dyn_tail(&ctx->outbuf, buflen - (size_t)written); + return CURLE_AGAIN; } else { Curl_dyn_reset(&ctx->outbuf); @@ -867,6 +868,14 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, return NGHTTP2_ERR_CALLBACK_FAILURE; } } + if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { + /* Stream has ended. If there is pending data, ensure that read + will occur to consume it. */ + if(!data->state.drain && stream->memlen) { + drain_this(cf, data_s); + Curl_expire(data, 0, EXPIRE_RUN_NOW); + } + } break; case NGHTTP2_HEADERS: DEBUGF(LOG_CF(data_s, cf, "[h2sid=%u] recv frame HEADERS", stream_id)); @@ -1790,6 +1799,7 @@ static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, stream->pausedata += nread; stream->pauselen -= nread; + drain_this(cf, data); if(stream->pauselen == 0) { DEBUGF(LOG_CF(data, cf, "[h2sid=%u] Unpaused", stream->stream_id)); @@ -1798,18 +1808,6 @@ static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, stream->pausedata = NULL; stream->pauselen = 0; - - /* When NGHTTP2_ERR_PAUSE is returned from - data_source_read_callback, we might not process DATA frame - fully. Calling nghttp2_session_mem_recv() again will - continue to process DATA frame, but if there is no incoming - frames, then we have to call it again with 0-length data. - Without this, on_stream_close callback will not be called, - and stream could be hanged. */ - if(h2_process_pending_input(cf, data, err) != 0) { - nread = -1; - goto out; - } } DEBUGF(LOG_CF(data, cf, "[h2sid=%u] recv: returns unpaused %zd bytes", stream->stream_id, nread)); @@ -1933,6 +1931,7 @@ static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, drained_transfer(cf, data); } + *err = CURLE_OK; nread = retlen; DEBUGF(LOG_CF(data, cf, "[h2sid=%u] cf_h2_recv -> %zd", stream->stream_id, nread)); diff --git a/libs/libcurl/src/krb5.c b/libs/libcurl/src/krb5.c index da3e3577d9..6aed067feb 100644 --- a/libs/libcurl/src/krb5.c +++ b/libs/libcurl/src/krb5.c @@ -210,7 +210,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn) struct gss_channel_bindings_struct chan; size_t base64_sz = 0; struct sockaddr_in *remote_addr = - (struct sockaddr_in *)&conn->remote_addr->sa_addr; + (struct sockaddr_in *)(void *)&conn->remote_addr->sa_addr; char *stringp; if(getsockname(conn->sock[FIRSTSOCKET], diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist index 5b669cf5a6..29888b765f 100644 --- a/libs/libcurl/src/libcurl.plist +++ b/libs/libcurl/src/libcurl.plist @@ -15,7 +15,7 @@ se.curl.libcurl CFBundleVersion - 7.88.0 + 7.88.1 CFBundleName libcurl @@ -27,9 +27,9 @@ ???? CFBundleShortVersionString - libcurl 7.88.0 + libcurl 7.88.1 CFBundleGetInfoString - libcurl.plist 7.88.0 + libcurl.plist 7.88.1 diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c index d1a9499c7b..53e53ad6f5 100644 --- a/libs/libcurl/src/setopt.c +++ b/libs/libcurl/src/setopt.c @@ -895,22 +895,38 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * the listed enums in curl/curl.h. */ arg = va_arg(param, long); - if(arg < CURL_HTTP_VERSION_NONE) - return CURLE_BAD_FUNCTION_ARGUMENT; + switch(arg) { + case CURL_HTTP_VERSION_NONE: +#ifdef USE_HTTP2 + /* TODO: this seems an undesirable quirk to force a behaviour on + * lower implementations that they should recognize independantly? */ + arg = CURL_HTTP_VERSION_2TLS; +#endif + /* accepted */ + break; + case CURL_HTTP_VERSION_1_0: + case CURL_HTTP_VERSION_1_1: + /* accepted */ + break; +#ifdef USE_HTTP2 + case CURL_HTTP_VERSION_2_0: + case CURL_HTTP_VERSION_2TLS: + case CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE: + /* accepted */ + break; +#endif #ifdef ENABLE_QUIC - if(arg == CURL_HTTP_VERSION_3) - ; - else + case CURL_HTTP_VERSION_3: + case CURL_HTTP_VERSION_3ONLY: + /* accepted */ + break; #endif -#ifndef USE_HTTP2 - if(arg >= CURL_HTTP_VERSION_2) - return CURLE_UNSUPPORTED_PROTOCOL; -#else - if(arg >= CURL_HTTP_VERSION_LAST) + default: + /* not accepted */ + if(arg < CURL_HTTP_VERSION_NONE) + return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_UNSUPPORTED_PROTOCOL; - if(arg == CURL_HTTP_VERSION_NONE) - arg = CURL_HTTP_VERSION_2TLS; -#endif + } data->set.httpwant = (unsigned char)arg; break; diff --git a/libs/libcurl/src/setup-os400.h b/libs/libcurl/src/setup-os400.h index 7a6f6e1023..fbae57a44d 100644 --- a/libs/libcurl/src/setup-os400.h +++ b/libs/libcurl/src/setup-os400.h @@ -205,7 +205,7 @@ extern OM_uint32 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status, extern int Curl_os400_connect(int sd, struct sockaddr *destaddr, int addrlen); extern int Curl_os400_bind(int sd, struct sockaddr *localaddr, int addrlen); extern int Curl_os400_sendto(int sd, char *buffer, int buflen, int flags, - struct sockaddr *dstaddr, int addrlen); + const struct sockaddr *dstaddr, int addrlen); extern int Curl_os400_recvfrom(int sd, char *buffer, int buflen, int flags, struct sockaddr *fromaddr, int *addrlen); extern int Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen); diff --git a/libs/libcurl/src/socketpair.c b/libs/libcurl/src/socketpair.c index 5d0593e09b..5bba59ed90 100644 --- a/libs/libcurl/src/socketpair.c +++ b/libs/libcurl/src/socketpair.c @@ -85,9 +85,22 @@ int Curl_socketpair(int domain, int type, int protocol, socks[0] = socks[1] = CURL_SOCKET_BAD; +#if defined(WIN32) || defined(__CYGWIN__) + /* don't set SO_REUSEADDR on Windows */ + (void)reuse; +#ifdef SO_EXCLUSIVEADDRUSE + { + int exclusive = 1; + if(setsockopt(listener, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, + (char *)&exclusive, (curl_socklen_t)sizeof(exclusive)) == -1) + goto error; + } +#endif +#else if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, (curl_socklen_t)sizeof(reuse)) == -1) goto error; +#endif if(bind(listener, &a.addr, sizeof(a.inaddr)) == -1) goto error; if(getsockname(listener, &a.addr, &addrlen) == -1 || @@ -113,14 +126,52 @@ int Curl_socketpair(int domain, int type, int protocol, goto error; else { struct curltime check; - struct curltime now = Curl_now(); + struct curltime start = Curl_now(); + char *p = (char *)✓ + size_t s = sizeof(check); /* write data to the socket */ - swrite(socks[0], &now, sizeof(now)); + swrite(socks[0], &start, sizeof(start)); /* verify that we read the correct data */ - if((sizeof(now) != sread(socks[1], &check, sizeof(check)) || - memcmp(&now, &check, sizeof(check)))) - goto error; + do { + ssize_t nread; + + pfd[0].fd = socks[1]; + pfd[0].events = POLLIN; + pfd[0].revents = 0; + (void)Curl_poll(pfd, 1, 1000); /* one second */ + + nread = sread(socks[1], p, s); + if(nread == -1) { + int sockerr = SOCKERRNO; + /* Don't block forever */ + if(Curl_timediff(Curl_now(), start) > (60 * 1000)) + goto error; + if( +#ifdef WSAEWOULDBLOCK + /* This is how Windows does it */ + (WSAEWOULDBLOCK == sockerr) +#else + /* errno may be EWOULDBLOCK or on some systems EAGAIN when it + returned due to its inability to send off data without + blocking. We therefore treat both error codes the same here */ + (EWOULDBLOCK == sockerr) || (EAGAIN == sockerr) || + (EINTR == sockerr) || (EINPROGRESS == sockerr) +#endif + ) { + continue; + } + goto error; + } + s -= nread; + if(s) { + p += nread; + continue; + } + if(memcmp(&start, &check, sizeof(check))) + goto error; + break; + } while(1); } sclose(listener); diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c index e78e383896..e09df3df4b 100644 --- a/libs/libcurl/src/socks.c +++ b/libs/libcurl/src/socks.c @@ -316,7 +316,7 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, /* DNS resolve only for SOCKS4, not SOCKS4a */ if(!protocol4a) { enum resolve_t rc = - Curl_resolv(data, sx->hostname, sx->remote_port, FALSE, &dns); + Curl_resolv(data, sx->hostname, sx->remote_port, TRUE, &dns); if(rc == CURLRESOLV_ERROR) return CURLPX_RESOLVE_HOST; @@ -783,7 +783,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, case CONNECT_REQ_INIT: if(socks5_resolve_local) { enum resolve_t rc = Curl_resolv(data, sx->hostname, sx->remote_port, - FALSE, &dns); + TRUE, &dns); if(rc == CURLRESOLV_ERROR) return CURLPX_RESOLVE_HOST; diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c index 8c32bb8404..6d0ed31e52 100644 --- a/libs/libcurl/src/transfer.c +++ b/libs/libcurl/src/transfer.c @@ -1055,6 +1055,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, { struct SingleRequest *k = &data->req; CURLcode result; + struct curltime now; int didwhat = 0; curl_socket_t fd_read; @@ -1124,7 +1125,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, } #endif - k->now = Curl_now(); + now = Curl_now(); if(!didwhat) { /* no read no write, this is a timeout? */ if(k->exp100 == EXP100_AWAITING_CONTINUE) { @@ -1141,7 +1142,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, */ - timediff_t ms = Curl_timediff(k->now, k->start100); + timediff_t ms = Curl_timediff(now, k->start100); if(ms >= data->set.expect_100_timeout) { /* we've waited long enough, continue anyway */ k->exp100 = EXP100_SEND_DATA; @@ -1159,23 +1160,23 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(Curl_pgrsUpdate(data)) result = CURLE_ABORTED_BY_CALLBACK; else - result = Curl_speedcheck(data, k->now); + result = Curl_speedcheck(data, now); if(result) goto out; if(k->keepon) { - if(0 > Curl_timeleft(data, &k->now, FALSE)) { + if(0 > Curl_timeleft(data, &now, FALSE)) { if(k->size != -1) { failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_timediff(k->now, data->progress.t_startsingle), + Curl_timediff(now, data->progress.t_startsingle), k->bytecount, k->size); } else { failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T " milliseconds with %" CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_timediff(k->now, data->progress.t_startsingle), + Curl_timediff(now, data->progress.t_startsingle), k->bytecount); } result = CURLE_OPERATION_TIMEDOUT; diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c index 484c4eec25..3a81266424 100644 --- a/libs/libcurl/src/url.c +++ b/libs/libcurl/src/url.c @@ -3962,7 +3962,6 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn) data->state.httpreq = HTTPREQ_HEAD; k->start = Curl_now(); /* start time */ - k->now = k->start; /* current time is now */ k->header = TRUE; /* assume header */ k->bytecount = 0; k->ignorebody = FALSE; diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c index 24cfcf1acf..94266c1f4f 100644 --- a/libs/libcurl/src/urlapi.c +++ b/libs/libcurl/src/urlapi.c @@ -493,35 +493,21 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u, UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host, bool has_scheme) { - char *portptr = NULL; - char endbracket; - int len; + char *portptr; char *hostname = Curl_dyn_ptr(host); /* * Find the end of an IPv6 address, either on the ']' ending bracket or * a percent-encoded zone index. */ - if(1 == sscanf(hostname, "[%*45[0123456789abcdefABCDEF:.]%c%n", - &endbracket, &len)) { - if(']' == endbracket) - portptr = &hostname[len]; - else if('%' == endbracket) { - int zonelen = len; - if(1 == sscanf(hostname + zonelen, "%*[^]]%c%n", &endbracket, &len)) { - if(']' != endbracket) - return CURLUE_BAD_IPV6; - portptr = &hostname[--zonelen + len + 1]; - } - else - return CURLUE_BAD_IPV6; - } - else + if(hostname[0] == '[') { + portptr = strchr(hostname, ']'); + if(!portptr) return CURLUE_BAD_IPV6; - + portptr++; /* this is a RFC2732-style specified IP-address */ - if(portptr && *portptr) { + if(*portptr) { if(*portptr != ':') - return CURLUE_BAD_IPV6; + return CURLUE_BAD_PORT_NUMBER; } else portptr = NULL; @@ -585,11 +571,9 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname, hostname++; hlen -= 2; - if(hostname[hlen] != ']') - return CURLUE_BAD_IPV6; - - /* only valid letters are ok */ + /* only valid IPv6 letters are ok */ len = strspn(hostname, l); + if(hlen != len) { hlen = len; if(hostname[len] == '%') { @@ -603,8 +587,7 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname, while(*h && (*h != ']') && (i < 15)) zoneid[i++] = *h++; if(!i || (']' != *h)) - /* impossible to reach? */ - return CURLUE_MALFORMED_INPUT; + return CURLUE_BAD_IPV6; zoneid[i] = 0; u->zoneid = strdup(zoneid); if(!u->zoneid) diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h index 12e9441e11..c1efd65a8b 100644 --- a/libs/libcurl/src/urldata.h +++ b/libs/libcurl/src/urldata.h @@ -630,7 +630,6 @@ struct SingleRequest { curl_off_t pendingheader; /* this many bytes left to send is actually header and not body */ struct curltime start; /* transfer started at this time */ - struct curltime now; /* current time */ enum { HEADER_NORMAL, /* no bad header at all */ HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest -- cgit v1.2.3