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

@ -55,6 +55,9 @@
#include "strparse.h"
/* The curlx_str_* parsing functions */
#include "strcopy.h"
/* curlx_strcopy */
#include "dynbuf.h"
/* The curlx_dyn_* functions */

View file

@ -33,6 +33,7 @@
#include "inet_ntop.h"
#include "snprintf.h"
#include "strcopy.h"
#define IN6ADDRSZ 16
/* #define INADDRSZ 4 */
@ -78,7 +79,7 @@ static char *inet_ntop4(const unsigned char *src, char *dst, size_t size)
#endif
return NULL;
}
strcpy(dst, tmp);
curlx_strcopy(dst, size, tmp, len);
return dst;
}
@ -183,8 +184,7 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size)
*tp++ = ':';
*tp++ = '\0';
/* Check for overflow, copy, and we are done.
*/
/* Check for overflow, copy, and we are done. */
if((size_t)(tp - tmp) > size) {
#ifdef USE_WINSOCK
errno = WSAEINVAL;
@ -193,7 +193,8 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size)
#endif
return NULL;
}
strcpy(dst, tmp);
curlx_strcopy(dst, size, tmp, strlen(tmp));
return dst;
}

49
lib/curlx/strcopy.c Normal file
View file

@ -0,0 +1,49 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "../curl_setup.h"
#include "strcopy.h"
/*
* curlx_strcopy() is a replacement for strcpy().
*
* Provide the target buffer @dest and size of the target buffer @dsize, If
* the source string @src with its *string length* @slen fits in the target
* buffer it will be copied there - including storing a null terminator.
*
* If the target buffer is too small, the copy is not performed but if the
* target buffer has a non-zero size it will get a null terminator stored.
*/
void curlx_strcopy(char *dest, /* destination buffer */
size_t dsize, /* size of target buffer */
const char *src, /* source string */
size_t slen) /* length of source string to copy */
{
DEBUGASSERT(slen < dsize);
if(slen < dsize) {
memcpy(dest, src, slen);
dest[slen] = 0;
}
else if(dsize)
dest[0] = 0;
}

32
lib/curlx/strcopy.h Normal file
View file

@ -0,0 +1,32 @@
#ifndef HEADER_CURLX_STRCOPY_H
#define HEADER_CURLX_STRCOPY_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
void curlx_strcopy(char *dest,
size_t dsize, /* size of target buffer */
const char *src,
size_t slen); /* length of string to copy */
#endif /* HEADER_CURLX_STRCOPY_H */

View file

@ -35,6 +35,7 @@
#include "winapi.h"
#include "snprintf.h"
#include "strerr.h"
#include "strcopy.h"
#ifdef USE_WINSOCK
/* This is a helper function for curlx_strerror that converts Winsock error
@ -224,8 +225,7 @@ static const char *get_winsock_error(int err, char *buf, size_t len)
return NULL;
}
alen = strlen(p);
if(alen < len)
strcpy(buf, p);
curlx_strcopy(buf, len, p, alen);
return buf;
#endif
}

View file

@ -30,6 +30,7 @@
#ifdef _WIN32
#include "winapi.h"
#include "snprintf.h"
#include "strcopy.h"
/* This is a helper function for curlx_strerror that converts Windows API error
* codes (GetLastError) to error messages.
@ -93,8 +94,7 @@ const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen)
#else
{
const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error";
if(strlen(txt) < buflen)
strcpy(buf, txt);
curlx_strcopy(buf, buflen, txt, strlen(txt));
}
#endif