From b20b364764cca2d577640126494fe2b09ae22e5d Mon Sep 17 00:00:00 2001 From: Patrick Monnerat Date: Mon, 25 Oct 2021 12:58:37 +0200 Subject: mime: use percent-escaping for multipart form field and file names Until now, form field and file names where escaped using the backslash-escaping algorithm defined for multipart mails. This commit replaces this with the percent-escaping method for URLs. As this may introduce incompatibilities with server-side applications, a new libcurl option CURLOPT_MIME_OPTIONS with bitmask CURLMIMEOPT_FORMESCAPE is introduced to revert to legacy use of backslash-escaping. This is controlled by new cli tool option --form-escape. New tests and documentation are provided for this feature. Reported by: Ryan Sleevi Fixes #7789 Closes #7805 --- src/tool_cfgable.h | 1 + src/tool_getparam.c | 7 +++++++ src/tool_listhelp.c | 3 +++ src/tool_operate.c | 4 ++++ 4 files changed, 15 insertions(+) (limited to 'src') diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index eff55f95d..227b914e3 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -239,6 +239,7 @@ struct OperationConfig { char *ftp_account; /* for ACCT */ char *ftp_alternative_to_user; /* send command if USER/PASS fails */ int ftp_filemethod; + long mime_options; /* Mime option flags. */ long tftp_blksize; /* TFTP BLKSIZE option */ bool tftp_no_options; /* do not send TFTP options requests */ bool ignorecl; /* --ignore-content-length */ diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 1fe7d5d09..7abbcc639 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -138,6 +138,7 @@ static const struct LongShort aliases[]= { {"$h", "retry-delay", ARG_STRING}, {"$i", "retry-max-time", ARG_STRING}, {"$k", "proxy-negotiate", ARG_BOOL}, + {"$l", "form-escape", ARG_BOOL}, {"$m", "ftp-account", ARG_STRING}, {"$n", "proxy-anyauth", ARG_BOOL}, {"$o", "trace-time", ARG_BOOL}, @@ -988,6 +989,12 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ return PARAM_LIBCURL_DOESNT_SUPPORT; break; + case 'l': /* --form-escape */ + config->mime_options &= ~CURLMIMEOPT_FORMESCAPE; + if(toggle) + config->mime_options |= CURLMIMEOPT_FORMESCAPE; + break; + case 'm': /* --ftp-account */ GetStr(&config->ftp_account, nextarg); break; diff --git a/src/tool_listhelp.c b/src/tool_listhelp.c index ce92ec02c..4bb9fd4b5 100644 --- a/src/tool_listhelp.c +++ b/src/tool_listhelp.c @@ -193,6 +193,9 @@ const struct helptxt helptext[] = { {"-F, --form ", "Specify multipart MIME data", CURLHELP_HTTP | CURLHELP_UPLOAD}, + {" --form-escape", + "Escape multipart form field/file names using backslash", + CURLHELP_HTTP | CURLHELP_POST}, {" --form-string ", "Specify multipart MIME data", CURLHELP_HTTP | CURLHELP_UPLOAD}, diff --git a/src/tool_operate.c b/src/tool_operate.c index ed3b2f56a..bbf743dab 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1325,6 +1325,10 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(result) break; + /* new in libcurl 7.81.0 */ + if(config->mime_options) + my_setopt(curl, CURLOPT_MIME_OPTIONS, config->mime_options); + /* new in libcurl 7.10.6 (default is Basic) */ if(config->authtype) my_setopt_bitmask(curl, CURLOPT_HTTPAUTH, (long)config->authtype); -- cgit v1.2.1