src: avoid strdup on platforms not doing UTF8 conversions

... and use more const strings.

Closes #16560
This commit is contained in:
Daniel Stenberg 2025-03-04 17:50:37 +01:00
parent 7298c4320b
commit ed15fce1fd
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
6 changed files with 73 additions and 41 deletions

View file

@ -84,7 +84,7 @@ typedef union {
#define curlx_unicodefree(ptr) \
do { \
if(ptr) { \
(free)(ptr); \
(free)((char *)ptr); \
(ptr) = NULL; \
} \
} while(0)

View file

@ -65,6 +65,27 @@ static ParameterError getstr(char **str, const char *val, bool allowblank)
return PARAM_OK;
}
static ParameterError getstrn(char **str, const char *val,
size_t len, bool allowblank)
{
if(*str) {
free(*str);
*str = NULL;
}
if(val) {
if(!allowblank && !val[0])
return PARAM_BLANK_STRING;
*str = malloc(len + 1);
if(!*str)
return PARAM_NO_MEM;
memcpy(*str, val, len);
(*str)[len] = 0; /* null terminate */
}
return PARAM_OK;
}
/* this array MUST be alphasorted based on the 'lname' */
static const struct LongShort aliases[]= {
{"abstract-unix-socket", ARG_FILE, ' ', C_ABSTRACT_UNIX_SOCKET},
@ -486,7 +507,7 @@ static size_t replace_url_encoded_space_by_plus(char *url)
}
static void
GetFileAndPassword(char *nextarg, char **file, char **password)
GetFileAndPassword(const char *nextarg, char **file, char **password)
{
char *certname, *passphrase;
if(nextarg) {
@ -572,7 +593,7 @@ static void cleanarg(argv_item_t str)
/* --data-urlencode */
static ParameterError data_urlencode(struct GlobalConfig *global,
char *nextarg,
const char *nextarg,
char **postp,
size_t *lenp)
{
@ -823,7 +844,7 @@ static int find_tos(const void *a, const void *b)
}
#define MAX_QUERY_LEN 100000 /* larger is not likely to ever work */
static ParameterError url_query(char *nextarg,
static ParameterError url_query(const char *nextarg,
struct GlobalConfig *global,
struct OperationConfig *config)
{
@ -860,7 +881,7 @@ static ParameterError url_query(char *nextarg,
}
static ParameterError set_data(cmdline_t cmd,
char *nextarg,
const char *nextarg,
struct GlobalConfig *global,
struct OperationConfig *config)
{
@ -941,7 +962,7 @@ static ParameterError set_data(cmdline_t cmd,
}
static ParameterError set_rate(struct GlobalConfig *global,
char *nextarg)
const char *nextarg)
{
/* --rate */
/* support a few different suffixes, extract the suffix first, then
@ -1133,12 +1154,15 @@ static ParameterError parse_url(struct GlobalConfig *global,
static ParameterError parse_localport(struct OperationConfig *config,
char *nextarg)
const char *nextarg)
{
char *pp = NULL;
char *p = nextarg;
const char *pp = NULL;
const char *p = nextarg;
char buffer[22];
size_t plen = 0;
while(ISDIGIT(*p))
p++;
plen = p - nextarg;
if(*p) {
pp = p;
/* check for ' - [end]' */
@ -1149,10 +1173,9 @@ static ParameterError parse_localport(struct OperationConfig *config,
pp++;
if(*pp && ISSPACE(*pp))
pp++;
*p = 0; /* null-terminate to make str2unum() work below */
}
if(str2unummax(&config->localport, nextarg, 65535))
msnprintf(buffer, sizeof(buffer), "%.*s", (int)plen, nextarg);
if(str2unummax(&config->localport, buffer, 65535))
return PARAM_BAD_USE;
if(!pp)
config->localportrange = 1; /* default number of ports to try */
@ -1694,7 +1717,7 @@ static ParameterError parse_upload_flags(struct OperationConfig *config,
}
ParameterError getparameter(const char *flag, /* f or -long-flag */
char *nextarg, /* NULL if unset */
const char *nextarg, /* NULL if unset */
argv_item_t cleararg1,
argv_item_t cleararg2,
bool *usedarg, /* set to TRUE if the arg
@ -2475,17 +2498,20 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
err = getstr(&config->headerfile, nextarg, DENY_BLANK);
break;
case C_REFERER: { /* --referer */
char *ptr = strstr(nextarg, ";auto");
const char *ptr = strstr(nextarg, ";auto");
size_t len;
if(ptr) {
/* Automatic referer requested, this may be combined with a
set initial one */
config->autoreferer = TRUE;
*ptr = 0; /* null-terminate here */
len = ptr - nextarg;
}
else
else {
config->autoreferer = FALSE;
ptr = *nextarg ? nextarg : NULL;
err = getstr(&config->referer, ptr, ALLOW_BLANK);
len = strlen(nextarg);
}
ptr = len ? nextarg : NULL;
err = getstrn(&config->referer, ptr, len, ALLOW_BLANK);
}
break;
case C_CERT: /* --cert */
@ -2993,7 +3019,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
error:
if(nextalloc)
free(nextarg);
free((char *)nextarg);
return err;
}
@ -3002,16 +3028,12 @@ ParameterError parse_args(struct GlobalConfig *global, int argc,
{
int i;
bool stillflags;
char *orig_opt = NULL;
const char *orig_opt = NULL;
ParameterError result = PARAM_OK;
struct OperationConfig *config = global->first;
for(i = 1, stillflags = TRUE; i < argc && !result; i++) {
#ifdef UNDER_CE
orig_opt = strdup(argv[i]);
#else
orig_opt = curlx_convert_tchar_to_UTF8(argv[i]);
#endif
orig_opt = convert_tchar_to_UTF8(argv[i]);
if(!orig_opt)
return PARAM_NO_MEM;
@ -3023,15 +3045,11 @@ ParameterError parse_args(struct GlobalConfig *global, int argc,
following (URL) argument to start with -. */
stillflags = FALSE;
else {
char *nextarg = NULL;
const char *nextarg = NULL;
if(i < (argc - 1)) {
#ifdef UNDER_CE
nextarg = strdup(argv[i + 1]);
#else
nextarg = curlx_convert_tchar_to_UTF8(argv[i + 1]);
#endif
nextarg = convert_tchar_to_UTF8(argv[i + 1]);
if(!nextarg) {
curlx_unicodefree(orig_opt);
unicodefree(orig_opt);
return PARAM_NO_MEM;
}
}
@ -3039,7 +3057,7 @@ ParameterError parse_args(struct GlobalConfig *global, int argc,
result = getparameter(orig_opt, nextarg, argv[i], argv[i + 1],
&passarg, global, config);
curlx_unicodefree(nextarg);
unicodefree(nextarg);
config = global->last;
if(result == PARAM_NEXT_OPERATION) {
/* Reset result as PARAM_NEXT_OPERATION is only used here and not
@ -3084,7 +3102,7 @@ ParameterError parse_args(struct GlobalConfig *global, int argc,
}
if(!result)
curlx_unicodefree(orig_opt);
unicodefree(orig_opt);
}
if(!result && config->content_disposition) {
@ -3105,6 +3123,6 @@ ParameterError parse_args(struct GlobalConfig *global, int argc,
helpf(tool_stderr, "%s", reason);
}
curlx_unicodefree(orig_opt);
unicodefree(orig_opt);
return result;
}

View file

@ -361,7 +361,7 @@ struct OperationConfig;
const struct LongShort *findlongopt(const char *opt);
const struct LongShort *findshortopt(char letter);
ParameterError getparameter(const char *flag, char *nextarg,
ParameterError getparameter(const char *flag, const char *nextarg,
argv_item_t cleararg1,
argv_item_t cleararg2,
bool *usedarg,
@ -377,4 +377,18 @@ void parse_cert_parameter(const char *cert_parameter,
ParameterError parse_args(struct GlobalConfig *config, int argc,
argv_item_t argv[]);
#if defined(UNICODE) && defined(_WIN32) && !defined(UNDER_CE)
#define convert_UTF8_to_tchar(ptr) curlx_convert_UTF8_to_wchar((ptr))
#define convert_tchar_to_UTF8(ptr) curlx_convert_wchar_to_UTF8((ptr))
#define unicodefree(ptr) curlx_unicodefree(ptr)
#else
#define convert_UTF8_to_tchar(ptr) (const char *)(ptr)
#define convert_tchar_to_UTF8(ptr) (const char *)(ptr)
#define unicodefree(ptr) do {} while(0)
#endif
#endif /* HEADER_CURL_TOOL_GETPARAM_H */

View file

@ -3161,11 +3161,11 @@ static CURLcode run_all_transfers(struct GlobalConfig *global,
CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[])
{
CURLcode result = CURLE_OK;
char *first_arg;
const char *first_arg;
#ifdef UNDER_CE
first_arg = argc > 1 ? strdup(argv[1]) : NULL;
#else
first_arg = argc > 1 ? curlx_convert_tchar_to_UTF8(argv[1]) : NULL;
first_arg = argc > 1 ? convert_tchar_to_UTF8(argv[1]) : NULL;
#endif
#ifdef HAVE_SETLOCALE
@ -3187,7 +3187,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[])
}
}
curlx_unicodefree(first_arg);
unicodefree(first_arg);
if(!result) {
/* Parse the command line arguments */

View file

@ -36,7 +36,7 @@ void tool_init_stderr(void)
tool_stderr = stderr;
}
void tool_set_stderr_file(struct GlobalConfig *global, char *filename)
void tool_set_stderr_file(struct GlobalConfig *global, const char *filename)
{
FILE *fp;

View file

@ -27,6 +27,6 @@
#include "tool_cfgable.h"
void tool_init_stderr(void);
void tool_set_stderr_file(struct GlobalConfig *global, char *filename);
void tool_set_stderr_file(struct GlobalConfig *global, const char *filename);
#endif /* HEADER_CURL_TOOL_STDERR_H */