From: Tom Eccles Date: Thu, 23 Jun 2022 09:09:25 +0000 (+0100) Subject: ftp: restore protocol state after http proxy CONNECT X-Git-Tag: curl-7_84_0~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=71bbabb16755c3d611bb24909e77a0df688827aa;p=thirdparty%2Fcurl.git ftp: restore protocol state after http proxy CONNECT connect_init() (lib/http_proxy.c) swaps out the protocol state while working on the proxy connection, this is then restored by Curl_connect_done() after the connection completes. ftp_do_more() extracted the protocol state pointer to a local variable at the start of the function then calls Curl_proxy_connect(). If the proxy connection completes, Curl_proxy_connect() will call Curl_connect_done() (via Curl_proxyCONNECT()), which restores data->req.p to point to the ftp protocol state instead of the http proxy protocol state, but the local variable in ftp_do_more still pointed to the old value. Ultimately this meant that the state worked on by ftp_do_more() was the http proxy state not the ftp state initialised by ftp_connect(), but subsequent calls to any ftp_ function would use the original state. For my use-case, the visible consequence was that ftp->downloadsize was never set and so downloaded data was never returned to the application. This commit updates the ftp protocol state pointer in ftp_do_more() after Curl_proxy_connect() returns, ensuring that the correct state pointer is used. Fixes #8737 Closes #9043 --- diff --git a/lib/ftp.c b/lib/ftp.c index ae2c90965d..e6e9821c9c 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -3565,8 +3565,10 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) bool connected = FALSE; bool complete = FALSE; - /* the ftp struct is inited in ftp_connect() */ - struct FTP *ftp = data->req.p.ftp; + /* the ftp struct is inited in ftp_connect(). If we are connecting to an HTTP + * proxy then the state will not be valid until after that connection is + * complete */ + struct FTP *ftp = NULL; /* if the second connection isn't done yet, wait for it */ if(!conn->bits.tcpconnect[SECONDARYSOCKET]) { @@ -3607,6 +3609,9 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) return result; #endif + /* Curl_proxy_connect might have moved the protocol state */ + ftp = data->req.p.ftp; + if(ftpc->state) { /* already in a state so skip the initial commands. They are only done to kickstart the do_more state */