mirror of
https://github.com/curl/curl.git
synced 2026-04-11 12:01:42 +08:00
curlx: move Curl_gmtime(), use gmtime_s() on Windows
Move `Curl_gmtime()` to curlx and rename to `curlx_gmtime()`. Then call
the internal wrapper also from the curl tool, to avoid using the banned
`gmtime()` directly, and using better, thread-safe alternatives when
available.
Windows `gmtime_s()` requires mingw-w64 v4+ or MSVC. Use local
workaround to also support mingw-w64 v3. `gmtime_s()` also makes
defining `_CRT_SECURE_NO_WARNINGS` unnecessary.
Also:
- lib: drop unused `parsedate.h` includes.
- drop redundant cast from `gmtime_r()` result.
- autotools: reverse condition in the proto detection to avoid
misleading readers. (the condition plays no role in detection.)
- note Windows XP's default `msvcrt.dll` doesn't offer secure CRT APIs.
XP likely needs a newer version of this DLL, or may not run.
Refs:
https://learn.microsoft.com/cpp/c-runtime-library/reference/gmtime-gmtime32-gmtime64
https://learn.microsoft.com/cpp/c-runtime-library/reference/gmtime-s-gmtime32-s-gmtime64-s
https://pubs.opengroup.org/onlinepubs/9799919799/functions/gmtime.html
https://linux.die.net/man/3/gmtime_r
Ref: #19957 (for `localtime_r()`)
Follow-up to 54d9f060b4
Closes #19955
This commit is contained in:
parent
74a2828279
commit
c6988f9131
@ -40,6 +40,7 @@
|
||||
#include "strdup.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "curlx/timeval.h"
|
||||
#include "connect.h"
|
||||
|
||||
#define MAX_ALTSVC_LINE 4095
|
||||
@ -241,7 +242,7 @@ static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
|
||||
const char *dst6_post = "";
|
||||
const char *src6_pre = "";
|
||||
const char *src6_post = "";
|
||||
CURLcode result = Curl_gmtime(as->expires, &stamp);
|
||||
CURLcode result = curlx_gmtime(as->expires, &stamp);
|
||||
if(result)
|
||||
return result;
|
||||
#ifdef USE_IPV6
|
||||
|
||||
@ -94,7 +94,7 @@
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE /* for close(), fileno(), unlink(), etc. */
|
||||
#endif
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS /* for getenv(), gmtime(), strcpy(),
|
||||
#define _CRT_SECURE_NO_WARNINGS /* for getenv(), strcpy(),
|
||||
in tests: localtime(), sscanf() */
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
@ -258,3 +258,39 @@ timediff_t curlx_timediff_us(struct curltime newer, struct curltime older)
|
||||
return TIMEDIFF_T_MIN;
|
||||
return diff * 1000000 + newer.tv_usec - older.tv_usec;
|
||||
}
|
||||
|
||||
#if defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR <= 3)
|
||||
#include <sec_api/time_s.h> /* for _gmtime32_s(), _gmtime64_s() */
|
||||
#ifdef _USE_32BIT_TIME_T
|
||||
#define gmtime_s _gmtime32_s
|
||||
#else
|
||||
#define gmtime_s _gmtime64_s
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* curlx_gmtime() is a gmtime() replacement for portability. Do not use
|
||||
* the gmtime_s(), gmtime_r() or gmtime() functions anywhere else but here.
|
||||
*/
|
||||
CURLcode curlx_gmtime(time_t intime, struct tm *store)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if(gmtime_s(store, &intime)) /* thread-safe */
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
#elif defined(HAVE_GMTIME_R)
|
||||
const struct tm *tm;
|
||||
tm = gmtime_r(&intime, store); /* thread-safe */
|
||||
if(!tm)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
#else
|
||||
const struct tm *tm;
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
tm = gmtime(&intime); /* not thread-safe */
|
||||
if(tm)
|
||||
*store = *tm; /* copy the pointed struct to the local copy */
|
||||
else
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -65,4 +65,6 @@ timediff_t curlx_timediff_ceil_ms(struct curltime newer,
|
||||
*/
|
||||
timediff_t curlx_timediff_us(struct curltime newer, struct curltime older);
|
||||
|
||||
CURLcode curlx_gmtime(time_t intime, struct tm *store);
|
||||
|
||||
#endif /* HEADER_CURL_TIMEVAL_H */
|
||||
|
||||
@ -65,6 +65,7 @@
|
||||
#include "url.h"
|
||||
#include "parsedate.h" /* for the week day and month names */
|
||||
#include "curlx/fopen.h"
|
||||
#include "curlx/timeval.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "curl_range.h"
|
||||
|
||||
@ -490,7 +491,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
|
||||
}
|
||||
|
||||
filetime = (time_t)statbuf.st_mtime;
|
||||
result = Curl_gmtime(filetime, &buffer);
|
||||
result = curlx_gmtime(filetime, &buffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
||||
@ -71,6 +71,7 @@
|
||||
#include "strdup.h"
|
||||
#include "curlx/strerr.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "curlx/timeval.h"
|
||||
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
@ -2110,7 +2111,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
|
||||
struct tm buffer;
|
||||
const struct tm *tm = &buffer;
|
||||
|
||||
result = Curl_gmtime(filetime, &buffer);
|
||||
result = curlx_gmtime(filetime, &buffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
||||
@ -40,6 +40,7 @@
|
||||
#include "curl_share.h"
|
||||
#include "strdup.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "curlx/timeval.h"
|
||||
|
||||
#define MAX_HSTS_LINE 4095
|
||||
#define MAX_HSTS_HOSTLEN 2048
|
||||
@ -288,7 +289,7 @@ static CURLcode hsts_push(struct Curl_easy *data,
|
||||
e.includeSubDomains = sts->includeSubDomains;
|
||||
|
||||
if(sts->expires != TIME_T_MAX) {
|
||||
result = Curl_gmtime((time_t)sts->expires, &stamp);
|
||||
result = curlx_gmtime((time_t)sts->expires, &stamp);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -311,7 +312,7 @@ static CURLcode hsts_out(struct stsentry *sts, FILE *fp)
|
||||
{
|
||||
struct tm stamp;
|
||||
if(sts->expires != TIME_T_MAX) {
|
||||
CURLcode result = Curl_gmtime((time_t)sts->expires, &stamp);
|
||||
CURLcode result = curlx_gmtime((time_t)sts->expires, &stamp);
|
||||
if(result)
|
||||
return result;
|
||||
curl_mfprintf(fp, "%s%s \"%d%02d%02d %02d:%02d:%02d\"\n",
|
||||
|
||||
@ -87,6 +87,7 @@
|
||||
#include "bufref.h"
|
||||
#include "curl_ctype.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "curlx/timeval.h"
|
||||
|
||||
/*
|
||||
* Forward declarations.
|
||||
@ -1786,7 +1787,7 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
/* no condition was asked for */
|
||||
return CURLE_OK;
|
||||
|
||||
result = Curl_gmtime(data->set.timevalue, &keeptime);
|
||||
result = curlx_gmtime(data->set.timevalue, &keeptime);
|
||||
if(result) {
|
||||
failf(data, "Invalid TIMEVALUE");
|
||||
return result;
|
||||
|
||||
@ -32,10 +32,10 @@
|
||||
#include "http_aws_sigv4.h"
|
||||
#include "curl_sha256.h"
|
||||
#include "transfer.h"
|
||||
#include "parsedate.h"
|
||||
#include "sendf.h"
|
||||
#include "escape.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "curlx/timeval.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@ -806,7 +806,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data)
|
||||
#else
|
||||
clock = time(NULL);
|
||||
#endif
|
||||
result = Curl_gmtime(clock, &tm);
|
||||
result = curlx_gmtime(clock, &tm);
|
||||
if(result) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -598,27 +598,3 @@ int Curl_getdate_capped(const char *p, time_t *tp)
|
||||
int rc = parsedate(p, tp);
|
||||
return (rc == PARSEDATE_FAIL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_gmtime() is a gmtime() replacement for portability. Do not use the
|
||||
* gmtime_r() or gmtime() functions anywhere else but here.
|
||||
*
|
||||
*/
|
||||
|
||||
CURLcode Curl_gmtime(time_t intime, struct tm *store)
|
||||
{
|
||||
const struct tm *tm;
|
||||
#ifdef HAVE_GMTIME_R
|
||||
/* thread-safe version */
|
||||
tm = (struct tm *)gmtime_r(&intime, store);
|
||||
#else
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
tm = gmtime(&intime);
|
||||
if(tm)
|
||||
*store = *tm; /* copy the pointed struct to the local copy */
|
||||
#endif
|
||||
|
||||
if(!tm)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -27,8 +27,6 @@
|
||||
extern const char * const Curl_wkday[7];
|
||||
extern const char * const Curl_month[12];
|
||||
|
||||
CURLcode Curl_gmtime(time_t intime, struct tm *store);
|
||||
|
||||
/* Curl_getdate_capped() differs from curl_getdate() in that this returns
|
||||
TIME_T_MAX in case the parsed time value was too big, instead of an
|
||||
error. */
|
||||
|
||||
@ -56,6 +56,7 @@
|
||||
#include "../select.h"
|
||||
#include "../strdup.h"
|
||||
#include "../curlx/fopen.h"
|
||||
#include "../curlx/timeval.h"
|
||||
#include "../curlx/warnless.h"
|
||||
#include "x509asn1.h"
|
||||
#include "../multiif.h"
|
||||
@ -178,7 +179,7 @@ static void showtime(struct Curl_easy *data, const char *text, time_t stamp)
|
||||
struct tm buffer;
|
||||
const struct tm *tm = &buffer;
|
||||
char str[96];
|
||||
CURLcode result = Curl_gmtime(stamp, &buffer);
|
||||
CURLcode result = curlx_gmtime(stamp, &buffer);
|
||||
if(result)
|
||||
return;
|
||||
|
||||
|
||||
@ -67,7 +67,6 @@
|
||||
#include "vtls_int.h"
|
||||
#include "vtls_scache.h"
|
||||
#include "x509asn1.h"
|
||||
#include "../parsedate.h"
|
||||
#include "../connect.h" /* for the connect timeout */
|
||||
#include "../select.h"
|
||||
#include "../multiif.h"
|
||||
|
||||
@ -63,7 +63,6 @@
|
||||
#include "vtls_int.h"
|
||||
#include "vtls_scache.h"
|
||||
#include "keylog.h"
|
||||
#include "../parsedate.h"
|
||||
#include "../connect.h" /* for the connect timeout */
|
||||
#include "../progress.h"
|
||||
#include "../select.h"
|
||||
|
||||
@ -2134,7 +2134,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GMTIME_R], [
|
||||
]],[[
|
||||
time_t tm = 1170352587;
|
||||
struct tm result;
|
||||
if(gmtime_r(&tm, &result) != 0)
|
||||
if(gmtime_r(&tm, &result) == 0)
|
||||
return 1;
|
||||
(void)result;
|
||||
]])
|
||||
|
||||
@ -548,7 +548,6 @@ static const char *outtime(const char *ptr, /* %time{ ... */
|
||||
ptr += 6;
|
||||
end = strchr(ptr, '}');
|
||||
if(end) {
|
||||
struct tm *utc;
|
||||
struct dynbuf format;
|
||||
char output[256]; /* max output time length */
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
@ -602,10 +601,10 @@ static const char *outtime(const char *ptr, /* %time{ ... */
|
||||
result = curlx_dyn_addn(&format, &ptr[i], 1);
|
||||
}
|
||||
if(!result) {
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
utc = gmtime(&secs);
|
||||
if(curlx_dyn_len(&format) && utc &&
|
||||
strftime(output, sizeof(output), curlx_dyn_ptr(&format), utc))
|
||||
struct tm utc;
|
||||
result = curlx_gmtime(secs, &utc);
|
||||
if(curlx_dyn_len(&format) && !result &&
|
||||
strftime(output, sizeof(output), curlx_dyn_ptr(&format), &utc))
|
||||
fputs(output, stream);
|
||||
curlx_dyn_free(&format);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user