Skip to content

Commit 3b3887a

Browse files
committed
src: extended checking of mktime() return value and capability
mktime() can legitimately return -1 under glibc and FreeBSD (and possibly others), namely for 1970-01-01T00:59:59+0100. This means the return value alone is not good enough to determine failure status. The Linux mktime(3) manpage gives a way out: [on error] leaves the tm->tm_wday member unmodified. Since tm_wday gets normalized to [0..6], using any other value as input allows to determine failure status.
1 parent 5fa7f44 commit 3b3887a

File tree

4 files changed

+16
-4
lines changed

4 files changed

+16
-4
lines changed

exch/midb/mail_engine.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,10 @@ static std::unique_ptr<CONDITION_TREE> me_ct_build_internal(const char *charset,
11101110
memset(&tmp_tm, 0, sizeof(tmp_tm));
11111111
if (strptime(argv[i], "%d-%b-%Y", &tmp_tm) == nullptr)
11121112
return {};
1113+
tmp_tm.tm_wday = -1;
11131114
ptree_node->ct_time = mktime(&tmp_tm);
1115+
if (ptree_node->ct_time == -1 && tmp_tm.tm_wday == -1)
1116+
return {};
11141117
} else if ('(' == argv[i][0]) {
11151118
len = strlen(argv[i]);
11161119
argv[i][len - 1] = '\0';

exch/nsp/common_util.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ void common_util_day_to_filetime(const char *day, FILETIME *pftime)
4040

4141
memset(&tmp_tm, 0, sizeof(tmp_tm));
4242
strptime(day, "%Y-%m-%d", &tmp_tm);
43+
tmp_tm.tm_wday = -1;
4344
tmp_time = mktime(&tmp_tm);
44-
if (tmp_time == -1) {
45+
if (tmp_time == -1 && tmp_tm.tm_wday == -1) {
4546
*pftime = {};
4647
return;
4748
}

lib/mapi/tnef.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ pack_result tnef_pull::g_attr(TNEF_ATTRIBUTE *r)
733733
case ATTRIBUTE_ID_DATERECD:
734734
case ATTRIBUTE_ID_ATTACHCREATEDATE:
735735
case ATTRIBUTE_ID_ATTACHMODIFYDATE:
736-
case ATTRIBUTE_ID_DATEMODIFY:
736+
case ATTRIBUTE_ID_DATEMODIFY: {
737737
r->pvalue = pext->anew<uint64_t>();
738738
if (r->pvalue == nullptr)
739739
return EXT_ERR_ALLOC;
@@ -750,11 +750,14 @@ pack_result tnef_pull::g_attr(TNEF_ATTRIBUTE *r)
750750
tmp_tm.tm_mday = tmp_dtr.day;
751751
tmp_tm.tm_mon = tmp_dtr.month - 1;
752752
tmp_tm.tm_year = tmp_dtr.year - 1900;
753-
tmp_tm.tm_wday = tmp_dtr.dow - 1;
753+
tmp_tm.tm_wday = -1;
754754
tmp_tm.tm_yday = 0;
755755
tmp_tm.tm_isdst = 0;
756-
*static_cast<uint64_t *>(r->pvalue) = rop_util_unix_to_nttime(mktime(&tmp_tm));
756+
auto newtime = mktime(&tmp_tm);
757+
*static_cast<uint64_t *>(r->pvalue) = newtime != -1 || tmp_tm.tm_wday != -1 ?
758+
rop_util_unix_to_nttime(newtime) : 0;
757759
break;
760+
}
758761
case ATTRIBUTE_ID_REQUESTRES:
759762
case ATTRIBUTE_ID_PRIORITY:
760763
r->pvalue = pext->anew<uint16_t>();

tools/mbop_main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,12 @@ static int xmktime(const char *str, time_t *out)
498498
fprintf(stderr, "\"%s\" not understood, error at \"%s\". Required format is \"2024-01-01T00:00:00\" [always local system time] or unixtime.\n", g_start_txt, end);
499499
return -1;
500500
}
501+
tm.tm_wday = -1;
501502
*out = mktime(&tm);
503+
if (*out == -1 && tm.tm_wday == -1) {
504+
fprintf(stderr, "\"%s\" not understood by mktime\n", g_start_txt);
505+
return -1;
506+
}
502507
return 0;
503508
}
504509

0 commit comments

Comments
 (0)