mirror of
https://github.com/curl/curl.git
synced 2026-01-18 17:21:26 +01:00
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:
@@ -31,6 +31,7 @@ LIB_CURLX_CFILES = \
|
||||
curlx/inet_pton.c \
|
||||
curlx/multibyte.c \
|
||||
curlx/nonblock.c \
|
||||
curlx/strcopy.c \
|
||||
curlx/strerr.c \
|
||||
curlx/strparse.c \
|
||||
curlx/timediff.c \
|
||||
@@ -51,6 +52,7 @@ LIB_CURLX_HFILES = \
|
||||
curlx/multibyte.h \
|
||||
curlx/nonblock.h \
|
||||
curlx/snprintf.h \
|
||||
curlx/strcopy.h \
|
||||
curlx/strerr.h \
|
||||
curlx/strparse.h \
|
||||
curlx/timediff.h \
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curl_gethostname.h"
|
||||
#include "curlx/strcopy.h"
|
||||
|
||||
/*
|
||||
* Curl_gethostname() is a wrapper around gethostname() which allows
|
||||
@@ -60,7 +60,7 @@ int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen)
|
||||
const char *force_hostname = getenv("CURL_GETHOSTNAME");
|
||||
if(force_hostname) {
|
||||
if(strlen(force_hostname) < (size_t)namelen)
|
||||
strcpy(name, force_hostname);
|
||||
curlx_strcopy(name, namelen, force_hostname, strlen(force_hostname));
|
||||
else
|
||||
return 1; /* cannot do it */
|
||||
err = 0;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "curl_gssapi.h"
|
||||
#include "curl_trc.h"
|
||||
#include "curlx/strcopy.h"
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#if defined(HAVE_GSSGNU) || !defined(_WIN32)
|
||||
@@ -224,7 +225,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
strcpy(ctx->creds, creds);
|
||||
curlx_strcopy(ctx->creds, sizeof(ctx->creds), creds, strlen(creds));
|
||||
ctx->flags = req_flags;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "curlx/strparse.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "vquic/vquic.h"
|
||||
#include "curlx/strcopy.h"
|
||||
|
||||
static void trc_write(struct Curl_easy *data, curl_infotype type,
|
||||
const char *ptr, size_t size)
|
||||
@@ -184,7 +185,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
|
||||
len = curl_mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
|
||||
|
||||
if(data->set.errorbuffer && !data->state.errorbuf) {
|
||||
strcpy(data->set.errorbuffer, error);
|
||||
curlx_strcopy(data->set.errorbuffer, CURL_ERROR_SIZE, error, len);
|
||||
data->state.errorbuf = TRUE; /* wrote error string */
|
||||
}
|
||||
error[len++] = '\n';
|
||||
|
||||
@@ -55,6 +55,9 @@
|
||||
#include "strparse.h"
|
||||
/* The curlx_str_* parsing functions */
|
||||
|
||||
#include "strcopy.h"
|
||||
/* curlx_strcopy */
|
||||
|
||||
#include "dynbuf.h"
|
||||
/* The curlx_dyn_* functions */
|
||||
|
||||
|
||||
@@ -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
49
lib/curlx/strcopy.c
Normal 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
32
lib/curlx/strcopy.h
Normal 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 */
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#include "select.h"
|
||||
#include "strcase.h"
|
||||
#include "easy_lock.h"
|
||||
#include "curlx/strcopy.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
#if defined(CURLRES_SYNCH) && \
|
||||
@@ -622,7 +623,7 @@ static struct Curl_addrinfo *get_localhost6(int port, const char *name)
|
||||
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
||||
memcpy(ca->ai_addr, &sa6, ss_size);
|
||||
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
|
||||
strcpy(ca->ai_canonname, name);
|
||||
curlx_strcopy(ca->ai_canonname, hostlen + 1, name, hostlen);
|
||||
return ca;
|
||||
}
|
||||
#else
|
||||
@@ -659,7 +660,7 @@ static struct Curl_addrinfo *get_localhost(int port, const char *name)
|
||||
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
||||
memcpy(ca->ai_addr, &sa, ss_size);
|
||||
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
|
||||
strcpy(ca->ai_canonname, name);
|
||||
curlx_strcopy(ca->ai_canonname, hostlen + 1, name, hostlen);
|
||||
|
||||
ca6 = get_localhost6(port, name);
|
||||
if(!ca6)
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "curl_share.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "curlx/timeval.h"
|
||||
#include "curlx/strcopy.h"
|
||||
|
||||
#define MAX_HSTS_LINE 4095
|
||||
#define MAX_HSTS_HOSTLEN 2048
|
||||
@@ -294,7 +295,7 @@ static CURLcode hsts_push(struct Curl_easy *data,
|
||||
stamp.tm_hour, stamp.tm_min, stamp.tm_sec);
|
||||
}
|
||||
else
|
||||
strcpy(e.expire, UNLIMITED);
|
||||
curlx_strcopy(e.expire, sizeof(e.expire), UNLIMITED, strlen(UNLIMITED));
|
||||
|
||||
sc = data->set.hsts_write(data, &e, i, data->set.hsts_write_userp);
|
||||
*stop = (sc != CURLSTS_OK);
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
#include "url.h"
|
||||
#include "bufref.h"
|
||||
#include "curl_sasl.h"
|
||||
|
||||
#include "curlx/strcopy.h"
|
||||
|
||||
/* meta key for storing protocol meta at easy handle */
|
||||
#define CURL_META_IMAP_EASY "meta:proto:imap:easy"
|
||||
@@ -1679,7 +1679,7 @@ static CURLcode imap_connect(struct Curl_easy *data, bool *done)
|
||||
imap_state(data, imapc, IMAP_SERVERGREET);
|
||||
|
||||
/* Start off with an response id of '*' */
|
||||
strcpy(imapc->resptag, "*");
|
||||
curlx_strcopy(imapc->resptag, sizeof(imapc->resptag), "*", 1);
|
||||
|
||||
result = imap_multi_statemach(data, done);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ struct Curl_easy;
|
||||
#include "curl_trc.h"
|
||||
#include "transfer.h"
|
||||
#include "strdup.h"
|
||||
#include "curlx/strcopy.h"
|
||||
#include "curlx/fopen.h"
|
||||
#include "curlx/base64.h"
|
||||
|
||||
@@ -602,7 +603,7 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
|
||||
}
|
||||
}
|
||||
if(softlinebreak) {
|
||||
strcpy(buf, "\x3D\x0D\x0A"); /* "=\r\n" */
|
||||
curlx_strcopy(buf, sizeof(buf), "\x3D\x0D\x0A", 3); /* "=\r\n" */
|
||||
len = 3;
|
||||
consumed = 0;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "progress.h"
|
||||
#include "transfer.h"
|
||||
#include "curlx/timeval.h"
|
||||
#include "curlx/strcopy.h"
|
||||
|
||||
/* check rate limits within this many recent milliseconds, at minimum. */
|
||||
#define MIN_RATE_LIMIT_PERIOD 3000
|
||||
@@ -37,18 +38,18 @@
|
||||
#ifndef CURL_DISABLE_PROGRESS_METER
|
||||
/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
|
||||
byte) */
|
||||
static void time2str(char *r, curl_off_t seconds)
|
||||
static void time2str(char *r, size_t rsize, curl_off_t seconds)
|
||||
{
|
||||
curl_off_t h;
|
||||
if(seconds <= 0) {
|
||||
strcpy(r, "--:--:--");
|
||||
curlx_strcopy(r, rsize, "--:--:--", 8);
|
||||
return;
|
||||
}
|
||||
h = seconds / 3600;
|
||||
if(h <= 99) {
|
||||
curl_off_t m = (seconds - (h * 3600)) / 60;
|
||||
curl_off_t s = (seconds - (h * 3600)) - (m * 60);
|
||||
curl_msnprintf(r, 9, "%2" FMT_OFF_T ":%02" FMT_OFF_T ":%02" FMT_OFF_T,
|
||||
curl_msnprintf(r, rsize, "%2" FMT_OFF_T ":%02" FMT_OFF_T ":%02" FMT_OFF_T,
|
||||
h, m, s);
|
||||
}
|
||||
else {
|
||||
@@ -57,21 +58,21 @@ static void time2str(char *r, curl_off_t seconds)
|
||||
curl_off_t d = seconds / 86400;
|
||||
h = (seconds - (d * 86400)) / 3600;
|
||||
if(d <= 999)
|
||||
curl_msnprintf(r, 9, "%3" FMT_OFF_T "d %02" FMT_OFF_T "h", d, h);
|
||||
curl_msnprintf(r, rsize, "%3" FMT_OFF_T "d %02" FMT_OFF_T "h", d, h);
|
||||
else
|
||||
curl_msnprintf(r, 9, "%7" FMT_OFF_T "d", d);
|
||||
curl_msnprintf(r, rsize, "%7" FMT_OFF_T "d", d);
|
||||
}
|
||||
}
|
||||
|
||||
/* The point of this function would be to return a string of the input data,
|
||||
but never longer than 6 columns (+ one zero byte).
|
||||
Add suffix k, M, G when suitable... */
|
||||
static char *max6data(curl_off_t bytes, char *max6)
|
||||
static char *max6out(curl_off_t bytes, char *max6, size_t mlen)
|
||||
{
|
||||
/* a signed 64-bit value is 8192 petabytes maximum, shown as
|
||||
8.0E (exabytes)*/
|
||||
if(bytes < 100000)
|
||||
curl_msnprintf(max6, 7, "%6" CURL_FORMAT_CURL_OFF_T, bytes);
|
||||
curl_msnprintf(max6, mlen, "%6" CURL_FORMAT_CURL_OFF_T, bytes);
|
||||
else {
|
||||
const char unit[] = { 'k', 'M', 'G', 'T', 'P', 'E', 0 };
|
||||
int k = 0;
|
||||
@@ -85,7 +86,7 @@ static char *max6data(curl_off_t bytes, char *max6)
|
||||
DEBUGASSERT(unit[k]);
|
||||
} while(unit[k]);
|
||||
/* xxx.yU */
|
||||
curl_msnprintf(max6, 7, "%3" CURL_FORMAT_CURL_OFF_T
|
||||
curl_msnprintf(max6, mlen, "%3" CURL_FORMAT_CURL_OFF_T
|
||||
".%" CURL_FORMAT_CURL_OFF_T "%c", nbytes,
|
||||
(bytes % 1024) / (1024 / 10), unit[k]);
|
||||
}
|
||||
@@ -528,9 +529,10 @@ static void progress_meter(struct Curl_easy *data)
|
||||
/* Since both happen at the same time, total expected duration is max. */
|
||||
total_estm.secs = CURLMAX(ul_estm.secs, dl_estm.secs);
|
||||
/* create the three time strings */
|
||||
time2str(time_left, total_estm.secs > 0 ? (total_estm.secs - cur_secs) : 0);
|
||||
time2str(time_total, total_estm.secs);
|
||||
time2str(time_spent, cur_secs);
|
||||
time2str(time_left, sizeof(time_left),
|
||||
total_estm.secs > 0 ? (total_estm.secs - cur_secs) : 0);
|
||||
time2str(time_total, sizeof(time_total), total_estm.secs);
|
||||
time2str(time_spent, sizeof(time_spent), cur_secs);
|
||||
|
||||
/* Get the total amount of data expected to get transferred */
|
||||
total_expected_size = p->ul_size_known ? p->ul.total_size : p->ul.cur_size;
|
||||
@@ -554,18 +556,24 @@ static void progress_meter(struct Curl_easy *data)
|
||||
"%3" FMT_OFF_T " %s "
|
||||
"%3" FMT_OFF_T " %s "
|
||||
"%3" FMT_OFF_T " %s %s %s %s %s %s %s",
|
||||
total_estm.percent, /* 3 letters */ /* total % */
|
||||
max6data(total_expected_size, max6[2]), /* total size */
|
||||
dl_estm.percent, /* 3 letters */ /* rcvd % */
|
||||
max6data(p->dl.cur_size, max6[0]), /* rcvd size */
|
||||
ul_estm.percent, /* 3 letters */ /* xfer % */
|
||||
max6data(p->ul.cur_size, max6[1]), /* xfer size */
|
||||
max6data(p->dl.speed, max6[3]), /* avrg dl speed */
|
||||
max6data(p->ul.speed, max6[4]), /* avrg ul speed */
|
||||
time_total, /* 8 letters */ /* total time */
|
||||
time_spent, /* 8 letters */ /* time spent */
|
||||
time_left, /* 8 letters */ /* time left */
|
||||
max6data(p->current_speed, max6[5])
|
||||
total_estm.percent, /* 3 letters */ /* total % */
|
||||
max6out(total_expected_size, max6[2],
|
||||
sizeof(max6[2])), /* total size */
|
||||
dl_estm.percent, /* 3 letters */ /* rcvd % */
|
||||
max6out(p->dl.cur_size, max6[0],
|
||||
sizeof(max6[0])), /* rcvd size */
|
||||
ul_estm.percent, /* 3 letters */ /* xfer % */
|
||||
max6out(p->ul.cur_size, max6[1],
|
||||
sizeof(max6[1])), /* xfer size */
|
||||
max6out(p->dl.speed, max6[3],
|
||||
sizeof(max6[3])), /* avrg dl speed */
|
||||
max6out(p->ul.speed, max6[4],
|
||||
sizeof(max6[4])), /* avrg ul speed */
|
||||
time_total, /* 8 letters */ /* total time */
|
||||
time_spent, /* 8 letters */ /* time spent */
|
||||
time_left, /* 8 letters */ /* time left */
|
||||
max6out(p->current_speed, max6[5],
|
||||
sizeof(max6[5])) /* current speed */
|
||||
);
|
||||
|
||||
/* we flush the output stream to make it appear as soon as possible */
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "curl_ntlm_core.h"
|
||||
#include "escape.h"
|
||||
#include "curl_endian.h"
|
||||
|
||||
#include "curlx/strcopy.h"
|
||||
|
||||
/* meta key for storing protocol meta at easy handle */
|
||||
#define CURL_META_SMB_EASY "meta:proto:smb:easy"
|
||||
@@ -790,7 +790,7 @@ static CURLcode smb_send_open(struct Curl_easy *data,
|
||||
msg.create_disposition = smb_swap32(SMB_FILE_OPEN);
|
||||
}
|
||||
msg.byte_count = smb_swap16((unsigned short)byte_count);
|
||||
strcpy(msg.bytes, req->path);
|
||||
curlx_strcopy(msg.bytes, sizeof(msg.bytes), req->path, byte_count - 1);
|
||||
|
||||
return smb_send_message(data, smbc, req, SMB_COM_NT_CREATE_ANDX, &msg,
|
||||
sizeof(msg) - sizeof(msg.bytes) + byte_count);
|
||||
|
||||
@@ -34,5 +34,4 @@ wchar_t *Curl_wcsdup(const wchar_t *src);
|
||||
void *Curl_memdup(const void *src, size_t buffer_length);
|
||||
void *Curl_saferealloc(void *ptr, size_t size);
|
||||
void *Curl_memdup0(const char *src, size_t length);
|
||||
|
||||
#endif /* HEADER_CURL_STRDUP_H */
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "curlx/winapi.h"
|
||||
#include "strerror.h"
|
||||
#include "curlx/strcopy.h"
|
||||
|
||||
const char *curl_easy_strerror(CURLcode error)
|
||||
{
|
||||
@@ -663,8 +664,7 @@ const char *Curl_sspi_strerror(SECURITY_STATUS err, char *buf, size_t buflen)
|
||||
txt = "No error";
|
||||
else
|
||||
txt = "Error";
|
||||
if(buflen > strlen(txt))
|
||||
strcpy(buf, txt);
|
||||
curlx_strcopy(buf, buflen, txt, strlen(txt));
|
||||
#endif
|
||||
|
||||
if(errno != old_errno)
|
||||
|
||||
35
lib/tftp.c
35
lib/tftp.c
@@ -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");
|
||||
|
||||
@@ -509,7 +509,7 @@ static CURLUcode ipv6_parse(struct Curl_URL *u, char *hostname,
|
||||
hostname[hlen] = 0; /* end the address there */
|
||||
if(curlx_inet_pton(AF_INET6, hostname, dest) != 1)
|
||||
return CURLUE_BAD_IPV6;
|
||||
if(curlx_inet_ntop(AF_INET6, dest, hostname, hlen)) {
|
||||
if(curlx_inet_ntop(AF_INET6, dest, hostname, hlen + 1)) {
|
||||
hlen = strlen(hostname); /* might be shorter now */
|
||||
hostname[hlen + 1] = 0;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "../url.h"
|
||||
#include "../bufref.h"
|
||||
#include "../curlx/strerr.h"
|
||||
#include "../curlx/strcopy.h"
|
||||
|
||||
/* A stream window is the maximum amount we need to buffer for
|
||||
* each active transfer. We use HTTP/3 flow control and only ACK
|
||||
@@ -141,7 +142,7 @@ static char *osslq_strerror(unsigned long error, char *buf, size_t size)
|
||||
if(!*buf) {
|
||||
const char *msg = error ? "Unknown error" : "No error";
|
||||
if(strlen(msg) < size)
|
||||
strcpy(buf, msg);
|
||||
curlx_strcopy(buf, size, msg, strlen(msg));
|
||||
}
|
||||
|
||||
return buf;
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "../multiif.h"
|
||||
#include "../curlx/strerr.h"
|
||||
#include "../curlx/strparse.h"
|
||||
#include "../curlx/strcopy.h"
|
||||
#include "../strdup.h"
|
||||
#include "apple.h"
|
||||
|
||||
@@ -773,8 +774,7 @@ static char *ossl_strerror(unsigned long error, char *buf, size_t size)
|
||||
|
||||
if(!*buf) {
|
||||
const char *msg = error ? "Unknown error" : "No error";
|
||||
if(strlen(msg) < size)
|
||||
strcpy(buf, msg);
|
||||
curlx_strcopy(buf, size, msg, strlen(msg));
|
||||
}
|
||||
|
||||
return buf;
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
#include "../select.h"
|
||||
#include "../setopt.h"
|
||||
#include "../strdup.h"
|
||||
#include "../curlx/strcopy.h"
|
||||
|
||||
#ifdef USE_APPLE_SECTRUST
|
||||
#include <Security/Security.h>
|
||||
@@ -1082,10 +1083,7 @@ static size_t multissl_version(char *buffer, size_t size)
|
||||
}
|
||||
|
||||
if(size) {
|
||||
if(backends_len < size)
|
||||
strcpy(buffer, backends);
|
||||
else
|
||||
*buffer = 0; /* did not fit */
|
||||
curlx_strcopy(buffer, size, backends, backends_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "../connect.h" /* for the connect timeout */
|
||||
#include "../progress.h"
|
||||
#include "../strdup.h"
|
||||
#include "../curlx/strcopy.h"
|
||||
#include "x509asn1.h"
|
||||
|
||||
#include <wolfssl/ssl.h>
|
||||
@@ -1542,8 +1543,7 @@ static char *wssl_strerror(unsigned long error, char *buf, unsigned long size)
|
||||
|
||||
if(!*buf) {
|
||||
const char *msg = error ? "Unknown error" : "No error";
|
||||
/* the string fits because the assert above assures this */
|
||||
strcpy(buf, msg);
|
||||
curlx_strcopy(buf, size, msg, strlen(msg));
|
||||
}
|
||||
|
||||
return buf;
|
||||
|
||||
3
lib/ws.c
3
lib/ws.c
@@ -40,6 +40,7 @@
|
||||
#include "transfer.h"
|
||||
#include "select.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "curlx/strcopy.h"
|
||||
|
||||
/***
|
||||
RFC 6455 Section 5.2
|
||||
@@ -1274,7 +1275,7 @@ CURLcode Curl_ws_request(struct Curl_easy *data, struct dynbuf *req)
|
||||
curlx_free(randstr);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
strcpy(keyval, randstr);
|
||||
curlx_strcopy(keyval, sizeof(keyval), randstr, randlen);
|
||||
curlx_free(randstr);
|
||||
for(i = 0; !result && (i < CURL_ARRAYSIZE(heads)); i++) {
|
||||
if(!Curl_checkheaders(data, heads[i].name, strlen(heads[i].name))) {
|
||||
|
||||
@@ -38,6 +38,7 @@ CURLX_CFILES = \
|
||||
../lib/curlx/fopen.c \
|
||||
../lib/curlx/multibyte.c \
|
||||
../lib/curlx/nonblock.c \
|
||||
../lib/curlx/strcopy.c \
|
||||
../lib/curlx/strerr.c \
|
||||
../lib/curlx/strparse.c \
|
||||
../lib/curlx/timediff.c \
|
||||
@@ -55,6 +56,7 @@ CURLX_HFILES = \
|
||||
../lib/curlx/multibyte.h \
|
||||
../lib/curlx/nonblock.h \
|
||||
../lib/curlx/snprintf.h \
|
||||
../lib/curlx/strcopy.h \
|
||||
../lib/curlx/strerr.h \
|
||||
../lib/curlx/strparse.h \
|
||||
../lib/curlx/timediff.h \
|
||||
|
||||
@@ -108,9 +108,7 @@ static void memory_tracking_init(void)
|
||||
if(env) {
|
||||
/* use the value as filename */
|
||||
char fname[512];
|
||||
if(strlen(env) >= sizeof(fname))
|
||||
env[sizeof(fname) - 1] = '\0';
|
||||
strcpy(fname, env);
|
||||
curlx_strcopy(fname, sizeof(fname), env, strlen(env));
|
||||
curl_free(env);
|
||||
curl_dbg_memdebug(fname);
|
||||
/* this weird stuff here is to make curl_free() get called before
|
||||
|
||||
@@ -29,13 +29,13 @@
|
||||
/* The point of this function would be to return a string of the input data,
|
||||
but never longer than 5 columns (+ one zero byte).
|
||||
Add suffix k, M, G when suitable... */
|
||||
static char *max5data(curl_off_t bytes, char *max5)
|
||||
static char *max5data(curl_off_t bytes, char *max5, size_t mlen)
|
||||
{
|
||||
/* a signed 64-bit value is 8192 petabytes maximum */
|
||||
const char unit[] = { 'k', 'M', 'G', 'T', 'P', 0 };
|
||||
const char unit[] = { 'k', 'M', 'G', 'T', 'P', 'E', 0 };
|
||||
int k = 0;
|
||||
if(bytes < 100000) {
|
||||
curl_msnprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes);
|
||||
curl_msnprintf(max5, mlen, "%5" CURL_FORMAT_CURL_OFF_T, bytes);
|
||||
return max5;
|
||||
}
|
||||
|
||||
@@ -43,14 +43,14 @@ static char *max5data(curl_off_t bytes, char *max5)
|
||||
curl_off_t nbytes = bytes / 1024;
|
||||
if(nbytes < 100) {
|
||||
/* display with a decimal */
|
||||
curl_msnprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
|
||||
curl_msnprintf(max5, mlen, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
|
||||
CURL_FORMAT_CURL_OFF_T "%c", bytes / 1024,
|
||||
(bytes % 1024) / (1024 / 10), unit[k]);
|
||||
break;
|
||||
}
|
||||
else if(nbytes < 10000) {
|
||||
/* no decimals */
|
||||
curl_msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "%c", nbytes,
|
||||
curl_msnprintf(max5, mlen, "%4" CURL_FORMAT_CURL_OFF_T "%c", nbytes,
|
||||
unit[k]);
|
||||
break;
|
||||
}
|
||||
@@ -87,18 +87,18 @@ int xferinfo_cb(void *clientp,
|
||||
|
||||
/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
|
||||
byte) */
|
||||
static void time2str(char *r, curl_off_t seconds)
|
||||
static void time2str(char *r, size_t rlen, curl_off_t seconds)
|
||||
{
|
||||
curl_off_t h;
|
||||
if(seconds <= 0) {
|
||||
strcpy(r, "--:--:--");
|
||||
curlx_strcopy(r, rlen, "--:--:--", 8);
|
||||
return;
|
||||
}
|
||||
h = seconds / 3600;
|
||||
if(h <= 99) {
|
||||
curl_off_t m = (seconds - (h * 3600)) / 60;
|
||||
curl_off_t s = (seconds - (h * 3600)) - (m * 60);
|
||||
curl_msnprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T
|
||||
curl_msnprintf(r, rlen, "%2" CURL_FORMAT_CURL_OFF_T
|
||||
":%02" CURL_FORMAT_CURL_OFF_T
|
||||
":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
|
||||
}
|
||||
@@ -108,10 +108,10 @@ static void time2str(char *r, curl_off_t seconds)
|
||||
curl_off_t d = seconds / 86400;
|
||||
h = (seconds - (d * 86400)) / 3600;
|
||||
if(d <= 999)
|
||||
curl_msnprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T
|
||||
curl_msnprintf(r, rlen, "%3" CURL_FORMAT_CURL_OFF_T
|
||||
"d %02" CURL_FORMAT_CURL_OFF_T "h", d, h);
|
||||
else
|
||||
curl_msnprintf(r, 9, "%7" CURL_FORMAT_CURL_OFF_T "d", d);
|
||||
curl_msnprintf(r, rlen, "%7" CURL_FORMAT_CURL_OFF_T "d", d);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,14 +254,14 @@ bool progress_meter(CURLM *multi, struct curltime *start, bool final)
|
||||
if(dlknown && speed) {
|
||||
curl_off_t est = all_dltotal / speed;
|
||||
curl_off_t left = (all_dltotal - all_dlnow) / speed;
|
||||
time2str(time_left, left);
|
||||
time2str(time_total, est);
|
||||
time2str(time_left, sizeof(time_left), left);
|
||||
time2str(time_total, sizeof(time_total), est);
|
||||
}
|
||||
else {
|
||||
time2str(time_left, 0);
|
||||
time2str(time_total, 0);
|
||||
time2str(time_left, sizeof(time_left), 0);
|
||||
time2str(time_total, sizeof(time_total), 0);
|
||||
}
|
||||
time2str(time_spent, spent);
|
||||
time2str(time_spent, sizeof(time_spent), spent);
|
||||
|
||||
(void)curl_multi_get_offt(multi, CURLMINFO_XFERS_ADDED, &xfers_added);
|
||||
(void)curl_multi_get_offt(multi, CURLMINFO_XFERS_RUNNING, &xfers_running);
|
||||
@@ -281,14 +281,14 @@ bool progress_meter(CURLM *multi, struct curltime *start, bool final)
|
||||
|
||||
dlpercen, /* 3 letters */
|
||||
ulpercen, /* 3 letters */
|
||||
max5data(all_dlnow, buffer[0]),
|
||||
max5data(all_ulnow, buffer[1]),
|
||||
max5data(all_dlnow, buffer[0], sizeof(buffer[0])),
|
||||
max5data(all_ulnow, buffer[1], sizeof(buffer[1])),
|
||||
xfers_added,
|
||||
xfers_running,
|
||||
time_total,
|
||||
time_spent,
|
||||
time_left,
|
||||
max5data(speed, buffer[2]), /* speed */
|
||||
max5data(speed, buffer[2], sizeof(buffer[2])), /* speed */
|
||||
final ? "\n" : "");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ CURLX_C = \
|
||||
../../lib/curl_threads.c \
|
||||
../../lib/curlx/fopen.c \
|
||||
../../lib/curlx/multibyte.c \
|
||||
../../lib/curlx/strcopy.c \
|
||||
../../lib/curlx/strerr.c \
|
||||
../../lib/curlx/strparse.c \
|
||||
../../lib/curlx/timediff.c \
|
||||
|
||||
@@ -40,6 +40,7 @@ CURLX_C = \
|
||||
../../lib/curlx/inet_pton.c \
|
||||
../../lib/curlx/multibyte.c \
|
||||
../../lib/curlx/nonblock.c \
|
||||
../../lib/curlx/strcopy.c \
|
||||
../../lib/curlx/strerr.c \
|
||||
../../lib/curlx/strparse.c \
|
||||
../../lib/curlx/timediff.c \
|
||||
|
||||
Reference in New Issue
Block a user