curlx: curlx_strcopy() instead of strcpy()

This function REQUIRES the size of the target buffer as well as the
length of the source string. Meant to make it harder to do a bad
strcpy().

Removes 23 calls to strcpy().

Closes #20067
This commit is contained in:
Daniel Stenberg 2025-12-21 23:40:24 +01:00
parent f099c2ca55
commit a535be4ea0
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
30 changed files with 195 additions and 97 deletions

View file

@ -62,6 +62,7 @@
#include "escape.h"
#include "curlx/strerr.h"
#include "curlx/strparse.h"
#include "curlx/strcopy.h"
/* RFC2348 allows the block size to be negotiated */
#define TFTP_BLKSIZE_DEFAULT 512
@ -369,12 +370,17 @@ static CURLcode tftp_parse_option_ack(struct tftp_conn *state,
}
static CURLcode tftp_option_add(struct tftp_conn *state, size_t *csize,
char *buf, const char *option)
size_t index, const char *option)
{
if((strlen(option) + *csize + 1) > (size_t)state->blksize)
char *buf = (char *)&state->spacket.data[index];
size_t oplen = strlen(option);
size_t blen;
if((state->blksize <= index) ||
(oplen + 1) > (size_t)(state->blksize - index))
return CURLE_TFTP_ILLEGAL;
strcpy(buf, option);
*csize += strlen(option) + 1;
blen = state->blksize - index;
curlx_strcopy(buf, blen, option, oplen);
*csize += oplen + 1;
return CURLE_OK;
}
@ -479,32 +485,23 @@ static CURLcode tftp_send_first(struct tftp_conn *state,
data->state.upload && (data->state.infilesize != -1) ?
data->state.infilesize : 0);
result = tftp_option_add(state, &sbytes,
(char *)state->spacket.data + sbytes,
TFTP_OPTION_TSIZE);
result = tftp_option_add(state, &sbytes, sbytes, TFTP_OPTION_TSIZE);
if(result == CURLE_OK)
result = tftp_option_add(state, &sbytes,
(char *)state->spacket.data + sbytes, buf);
result = tftp_option_add(state, &sbytes, sbytes, buf);
/* add blksize option */
curl_msnprintf(buf, sizeof(buf), "%d", state->requested_blksize);
if(result == CURLE_OK)
result = tftp_option_add(state, &sbytes,
(char *)state->spacket.data + sbytes,
TFTP_OPTION_BLKSIZE);
result = tftp_option_add(state, &sbytes, sbytes, TFTP_OPTION_BLKSIZE);
if(result == CURLE_OK)
result = tftp_option_add(state, &sbytes,
(char *)state->spacket.data + sbytes, buf);
result = tftp_option_add(state, &sbytes, sbytes, buf);
/* add timeout option */
curl_msnprintf(buf, sizeof(buf), "%d", state->retry_time);
if(result == CURLE_OK)
result = tftp_option_add(state, &sbytes,
(char *)state->spacket.data + sbytes,
TFTP_OPTION_INTERVAL);
result = tftp_option_add(state, &sbytes, sbytes, TFTP_OPTION_INTERVAL);
if(result == CURLE_OK)
result = tftp_option_add(state, &sbytes,
(char *)state->spacket.data + sbytes, buf);
result = tftp_option_add(state, &sbytes, sbytes, buf);
if(result != CURLE_OK) {
failf(data, "TFTP buffer too small for options");