From 7b11c5dbe612e152e4ee1b61bac872a7e7958578 Mon Sep 17 00:00:00 2001 From: Max Dymond Date: Wed, 25 Oct 2017 22:51:50 +0100 Subject: [PATCH] wildcards: don't use with non-supported protocols Fixes timeouts in the fuzzing tests for non-FTP protocols. Closes #2016 --- lib/ftp.c | 9 +++++---- lib/multi.c | 10 ++++++++-- lib/transfer.c | 3 ++- lib/url.c | 17 +++++++++-------- lib/urldata.h | 5 +++-- 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/lib/ftp.c b/lib/ftp.c index e9fab4f53c..5c7df2b4c6 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -182,7 +182,8 @@ const struct Curl_handler Curl_handler_ftp = { PORT_FTP, /* defport */ CURLPROTO_FTP, /* protocol */ PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD | - PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP /* flags */ + PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP | + PROTOPT_WILDCARD /* flags */ }; @@ -210,7 +211,7 @@ const struct Curl_handler Curl_handler_ftps = { PORT_FTPS, /* defport */ CURLPROTO_FTPS, /* protocol */ PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION | - PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY /* flags */ + PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD /* flags */ }; #endif @@ -3177,7 +3178,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, /* now store a copy of the directory we are in */ free(ftpc->prevpath); - if(data->set.wildcardmatch) { + if(data->state.wildcardmatch) { if(data->set.chunk_end && ftpc->file) { data->set.chunk_end(data->wildcard.customptr); } @@ -3962,7 +3963,7 @@ static CURLcode ftp_do(struct connectdata *conn, bool *done) *done = FALSE; /* default to false */ ftpc->wait_data_conn = FALSE; /* default to no such wait */ - if(conn->data->set.wildcardmatch) { + if(conn->data->state.wildcardmatch) { result = wc_statemach(conn); if(conn->data->wildcard.state == CURLWC_SKIP || conn->data->wildcard.state == CURLWC_DONE) { diff --git a/lib/multi.c b/lib/multi.c index bf0e89ae6a..658a18b15b 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1663,7 +1663,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(!result) { if(!dophase_done) { /* some steps needed for wildcard matching */ - if(data->set.wildcardmatch) { + if(data->state.wildcardmatch) { struct WildcardData *wc = &data->wildcard; if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) { /* skip some states if it is important */ @@ -1815,7 +1815,13 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, (data->easy_conn->writesockfd != CURL_SOCKET_BAD)) multistate(data, CURLM_STATE_WAITPERFORM); else + { + if(data->state.wildcardmatch && + ((data->easy_conn->handler->flags & PROTOPT_WILDCARD) == 0)) { + data->wildcard.state = CURLWC_DONE; + } multistate(data, CURLM_STATE_DONE); + } rc = CURLM_CALL_MULTI_PERFORM; break; @@ -2032,7 +2038,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->easy_conn = NULL; } - if(data->set.wildcardmatch) { + if(data->state.wildcardmatch) { if(data->wildcard.state != CURLWC_DONE) { /* if a wildcard is set and we are not ending -> lets start again with CURLM_STATE_INIT */ diff --git a/lib/transfer.c b/lib/transfer.c index c4cc160601..75659cf443 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -1344,6 +1344,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) if(result) return result; + data->state.wildcardmatch = data->set.wildcard_enabled; data->set.followlocation = 0; /* reset the location-follow counter */ data->state.this_is_a_follow = FALSE; /* reset this */ data->state.errorbuf = FALSE; /* no error has occurred */ @@ -1401,7 +1402,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) data->state.authhost.picked &= data->state.authhost.want; data->state.authproxy.picked &= data->state.authproxy.want; - if(data->set.wildcardmatch) { + if(data->state.wildcardmatch) { struct WildcardData *wc = &data->wildcard; if(wc->state < CURLWC_INIT) { result = Curl_wildcard_init(wc); /* init wildcard structures */ diff --git a/lib/url.c b/lib/url.c index 3a913dae88..f793809455 100644 --- a/lib/url.c +++ b/lib/url.c @@ -489,12 +489,8 @@ CURLcode Curl_close(struct Curl_easy *data) Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } - if(data->set.wildcardmatch) { - /* destruct wildcard structures if it is needed */ - struct WildcardData *wc = &data->wildcard; - Curl_wildcard_dtor(wc); - } - + /* destruct wildcard structures if it is needed */ + Curl_wildcard_dtor(&data->wildcard); Curl_freeset(data); free(data); return CURLE_OK; @@ -609,7 +605,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) return result; #endif - set->wildcardmatch = FALSE; + set->wildcard_enabled = FALSE; set->chunk_bgn = ZERO_NULL; set->chunk_end = ZERO_NULL; @@ -2966,7 +2962,7 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, break; case CURLOPT_WILDCARDMATCH: - data->set.wildcardmatch = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.wildcard_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE; break; case CURLOPT_CHUNK_BGN_FUNCTION: data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback); @@ -7225,6 +7221,11 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn) data->state.done = FALSE; /* *_done() is not called yet */ data->state.expect100header = FALSE; + /* if the protocol used doesn't support wildcards, switch it off */ + if(data->state.wildcardmatch && + !(conn->handler->flags & PROTOPT_WILDCARD)) + data->state.wildcardmatch = FALSE; + if(data->set.opt_no_body) /* in HTTP lingo, no body means using the HEAD request... */ data->set.httpreq = HTTPREQ_HEAD; diff --git a/lib/urldata.h b/lib/urldata.h index 964999c1fc..30e13a4523 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -719,6 +719,7 @@ struct Curl_handler { #define PROTOPT_PROXY_AS_HTTP (1<<11) /* allow this non-HTTP scheme over a HTTP proxy as HTTP proxies may know this protocol and act as a gateway */ +#define PROTOPT_WILDCARD (1<<12) /* protocol supports wildcard matching */ #define CONNCHECK_NONE 0 /* No checks */ #define CONNCHECK_ISDEAD (1<<0) /* Check if the connection is dead. */ @@ -1308,7 +1309,7 @@ struct UrlState { /* set after initial USER failure, to prevent an authentication loop */ bool ftp_trying_alternative; - + bool wildcardmatch; /* enable wildcard matching */ int httpversion; /* the lowest HTTP version*10 reported by any server involved in this request */ bool expect100header; /* TRUE if we added Expect: 100-continue */ @@ -1672,7 +1673,7 @@ struct UserDefined { /* Common RTSP header options */ Curl_RtspReq rtspreq; /* RTSP request type */ long rtspversion; /* like httpversion, for RTSP */ - bool wildcardmatch; /* enable wildcard matching */ + bool wildcard_enabled; /* enable wildcard matching */ curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer starts */ curl_chunk_end_callback chunk_end; /* called after part transferring