tool_getparam: parse_header() without strtok

Read a provided header file line-by-line instead. Avoids strtok(),
avoids a possibly quite large malloc for the entire file.

Closes #16572
This commit is contained in:
Daniel Stenberg 2025-03-05 13:43:48 +01:00
parent 5a3fe980c5
commit f79195e7ef
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2

View file

@ -1284,8 +1284,6 @@ static ParameterError parse_header(struct GlobalConfig *global,
/* A custom header to append to a list */
if(nextarg[0] == '@') {
/* read many headers from a file or stdin */
char *string;
size_t len;
bool use_stdin = !strcmp(&nextarg[1], "-");
FILE *file = use_stdin ? stdin : fopen(&nextarg[1], FOPEN_READTEXT);
if(!file) {
@ -1293,22 +1291,26 @@ static ParameterError parse_header(struct GlobalConfig *global,
err = PARAM_READ_ERROR;
}
else {
err = file2memory(&string, &len, file);
if(!err && string) {
/* Allow strtok() here since this is not used threaded */
/* !checksrc! disable BANNEDFUNC 2 */
char *h = strtok(string, "\r\n");
while(h) {
if(cmd == C_PROXY_HEADER) /* --proxy-header */
err = add2list(&config->proxyheaders, h);
else
err = add2list(&config->headers, h);
struct dynbuf line;
bool error = FALSE;
curlx_dyn_init(&line, 1024*100);
while(my_get_line(file, &line, &error)) {
/* every line has a newline that we strip off */
size_t len = curlx_dyn_len(&line);
if(len) {
const char *ptr;
curlx_dyn_setlen(&line, len - 1);
ptr = curlx_dyn_ptr(&line);
err = add2list(cmd == C_PROXY_HEADER ? /* --proxy-header? */
&config->proxyheaders :
&config->headers, ptr);
if(err)
break;
h = strtok(NULL, "\r\n");
}
free(string);
}
if(error)
err = PARAM_READ_ERROR;
curlx_dyn_free(&line);
if(!use_stdin)
fclose(file);
}
@ -1415,7 +1417,7 @@ static ParameterError parse_quote(struct OperationConfig *config,
/* prefixed with a plus makes it a just-before-transfer one */
nextarg++;
err = add2list(&config->prequote, nextarg);
break;
break;
default:
err = add2list(&config->quote, nextarg);
break;