Skip to content

Commit bd93f70

Browse files
committed
Improve gmtime/localtime usage
1 parent af477ec commit bd93f70

3 files changed

Lines changed: 61 additions & 34 deletions

File tree

.github/workflows/ZenLib_Checks.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ jobs:
6868
env:
6969
GENERATOR: "Unix Makefiles"
7070
CONFIGURATION: "Release"
71+
CXXFLAGS: -Werror
7172
steps:
7273
- name: Checkout ZenLib
7374
uses: actions/checkout@v5

Source/ZenLib/Format/Http/Http_Cookies.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,20 +86,28 @@ void Cookies::Create_Lines(std::ostream& Out)
8686
if (Cookie->second.Expires!=(time_t)-1)
8787
{
8888
char Temp[200];
89-
#if defined(HAVE_GMTIME_R)
90-
struct tm Gmt_Temp;
91-
struct tm *Gmt=gmtime_r(&Cookie->second.Expires, &Gmt_Temp);
92-
#elif defined(_MSC_VER)
93-
struct tm Gmt_Temp;
94-
errno_t gmtime_s_Result=gmtime_s(&Gmt_Temp , &Cookie->second.Expires);
95-
struct tm* Gmt=gmtime_s_Result?NULL:&Gmt_Temp;
89+
#if defined(_WIN32)
90+
#if _CRT_USE_CONFORMING_ANNEX_K_TIME || defined(__STDC_LIB_EXT1__)
91+
// C11 standard version on MSVC or MinGW
92+
tm Gmt_Temp;
93+
tm* Gmt = gmtime_s(&Cookie->second.Expires, &Gmt_Temp);
94+
#else
95+
// MSVC and MinGW-w64 argument order and return value differs from C11 standard
96+
tm Gmt_Temp;
97+
errno_t gmtime_s_Result = gmtime_s(&Gmt_Temp, &Cookie->second.Expires);
98+
tm* Gmt = gmtime_s_Result ? nullptr : &Gmt_Temp;
99+
#endif
100+
#elif defined(HAVE_GMTIME_R)
101+
// POSIX or C23
102+
tm Gmt_Temp;
103+
tm *Gmt = gmtime_r(&Cookie->second.Expires, &Gmt_Temp);
96104
#else
97-
#ifdef __GNUC__
98-
#warning "This version of ZenLib is not thread safe"
105+
// Fallback: not thread-safe, but prevents compile errors
106+
#ifdef __GNUC__
107+
#warning "This version of ZenLib is not thread safe"
108+
#endif
109+
tm *Gmt = gmtime(&Cookie->second.Expires);
99110
#endif
100-
struct tm *Gmt=gmtime(&Cookie->second.Expires);
101-
#endif
102-
103111
if (Gmt)
104112
if (strftime(Temp, 200, "%a, %d-%b-%Y %H:%M:%S GMT", Gmt))
105113
Out << "; expires=" << Temp;

Source/ZenLib/Ztring.cpp

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,18 +1306,27 @@ Ztring& Ztring::Date_From_Seconds_1970 (const int32s Value)
13061306
Ztring& Ztring::Date_From_Seconds_1970 (const int64s Value)
13071307
{
13081308
time_t Time=(time_t)Value;
1309-
#if defined(HAVE_GMTIME_R)
1310-
struct tm Gmt_Temp;
1311-
struct tm *Gmt=gmtime_r(&Time, &Gmt_Temp);
1312-
#elif defined(_MSC_VER)
1313-
struct tm Gmt_Temp;
1314-
errno_t gmtime_s_Result=gmtime_s(&Gmt_Temp , &Time);
1315-
struct tm* Gmt=gmtime_s_Result?NULL:&Gmt_Temp;
1309+
#if defined(_WIN32)
1310+
#if _CRT_USE_CONFORMING_ANNEX_K_TIME || defined(__STDC_LIB_EXT1__)
1311+
// C11 standard version on MSVC or MinGW
1312+
tm Gmt_Temp;
1313+
tm* Gmt = gmtime_s(&Time, &Gmt_Temp);
1314+
#else
1315+
// MSVC and MinGW-w64 argument order and return value differs from C11 standard
1316+
tm Gmt_Temp;
1317+
errno_t gmtime_s_Result = gmtime_s(&Gmt_Temp, &Time);
1318+
tm* Gmt = gmtime_s_Result ? nullptr : &Gmt_Temp;
1319+
#endif
1320+
#elif defined(HAVE_GMTIME_R)
1321+
// POSIX or C23
1322+
tm Gmt_Temp;
1323+
tm *Gmt = gmtime_r(&Time, &Gmt_Temp);
13161324
#else
1317-
#ifdef __GNUC__
1318-
#warning "This version of ZenLib is not thread safe"
1319-
#endif
1320-
struct tm *Gmt=gmtime(&Time);
1325+
// Fallback: not thread-safe, but prevents compile errors
1326+
#ifdef __GNUC__
1327+
#warning "This version of ZenLib is not thread safe"
1328+
#endif
1329+
tm *Gmt = gmtime(&Time);
13211330
#endif
13221331
if (!Gmt)
13231332
{
@@ -1349,18 +1358,27 @@ Ztring& Ztring::Date_From_Seconds_1970 (const int64s Value)
13491358
Ztring& Ztring::Date_From_Seconds_1970_Local (const int32u Value)
13501359
{
13511360
time_t Time=(time_t)Value;
1352-
#if defined(HAVE_LOCALTIME_R)
1353-
struct tm Gmt_Temp;
1354-
struct tm *Gmt=localtime_r(&Time, &Gmt_Temp);
1355-
#elif defined(_MSC_VER)
1356-
struct tm Gmt_Temp;
1357-
errno_t localtime_s_Result=localtime_s(&Gmt_Temp , &Time);
1358-
struct tm* Gmt=localtime_s_Result?NULL:&Gmt_Temp;
1361+
#if defined(_WIN32)
1362+
#if _CRT_USE_CONFORMING_ANNEX_K_TIME || defined(__STDC_LIB_EXT1__)
1363+
// C11 standard version on MSVC or MinGW
1364+
tm Gmt_Temp;
1365+
tm* Gmt = localtime_s(&Time, &Gmt_Temp);
1366+
#else
1367+
// MSVC and MinGW-w64 argument order and return value differs from C11 standard
1368+
tm Gmt_Temp;
1369+
errno_t localtime_s_Result = localtime_s(&Gmt_Temp, &Time);
1370+
tm* Gmt = localtime_s_Result ? nullptr : &Gmt_Temp;
1371+
#endif
1372+
#elif defined(HAVE_GMTIME_R)
1373+
// POSIX or C23
1374+
tm Gmt_Temp;
1375+
tm *Gmt = localtime_r(&Time, &Gmt_Temp);
13591376
#else
1360-
#ifdef __GNUC__
1361-
#warning "This version of ZenLib is not thread safe"
1362-
#endif
1363-
struct tm *Gmt=localtime(&Time);
1377+
// Fallback: not thread-safe, but prevents compile errors
1378+
#ifdef __GNUC__
1379+
#warning "This version of ZenLib is not thread safe"
1380+
#endif
1381+
tm *Gmt = localtime(&Time);
13641382
#endif
13651383
Ztring DateT;
13661384
Ztring Date;

0 commit comments

Comments
 (0)