fix(softcode): timefmt rejects unparseable seconds argument

SetSecondsString was ignored on failure, so a default-constructed
CLinearTimeAbsolute (FILETIME zero / 1601-01-01 UTC) was formatted.
In western zones that looked like "Sunday, December 31, 1600, 05:00 PM"
— e.g. timefmt(..., #-1 INVALID DATE) after a failed convtime().

Return #-1 INVALID DATE like convsecs/convtime on bad input. Smoke
TC004 pins the case.
This commit is contained in:
Stephen Dennis 2026-08-10 19:18:00 -06:00
parent 204e503199
commit e315994177
2 changed files with 32 additions and 3 deletions

View file

@ -1028,7 +1028,17 @@ static FUNCTION(fun_timefmt)
CLinearTimeAbsolute lta, ltaUTC;
if (nfargs == 2)
{
ltaUTC.SetSecondsString(fargs[1]);
// SetSecondsString fails closed without changing the absolute; a
// default-constructed ltaUTC is FILETIME zero (1601-01-01 UTC).
// Ignoring the failure made garbage such as "#-1 INVALID DATE"
// format as "Sunday, December 31, 1600, …" in western timezones
// instead of rejecting the seconds argument.
//
if (!ltaUTC.SetSecondsString(fargs[1]))
{
safe_str(S_("#-1 INVALID DATE"), buff, bufc);
return;
}
}
else
{

View file

@ -70,11 +70,30 @@
eq(strlen(timefmt($Y)), 4)
)=
{
@log smoke=TC003: timefmt documented shorthands. Succeeded.;
@log smoke=TC003: timefmt documented shorthands. Succeeded.
},
{
@log smoke=TC003: timefmt documented shorthands. Failed (F=[timefmt($F, 946684800)] ymd=[timefmt($Y-$m-$d, 946684800)] R=[timefmt($R, 946684800)] hm=[timefmt($H:$M, 946684800)] r=[timefmt($r, 946684800)]).
}
-
# Test Case #4 - timefmt rejects unparseable <secs> instead of formatting
# FILETIME zero (1601-01-01 UTC), which surfaces as Dec 31 1600 in western
# zones. A failed convtime() result fed into timefmt used to do exactly that.
# (Last case: @notify via tr.done so the suite can complete.)
#
&tr.tc004 test_etimefmt_fn=
@if cand(
strmatch(timefmt($A\, $B $d\, $Y\, $I:$M $p,#-1 INVALID DATE), #-1 INVALID DATE),
strmatch(timefmt($Y, not-a-number), #-1 INVALID DATE),
strmatch(timefmt($Y, xyzzy), #-1 INVALID DATE)
)=
{
@log smoke=TC004: timefmt invalid secs. Succeeded.;
@trig me/tr.done
},
{
@log smoke=TC003: timefmt documented shorthands. Failed (F=[timefmt($F, 946684800)] ymd=[timefmt($Y-$m-$d, 946684800)] R=[timefmt($R, 946684800)] hm=[timefmt($H:$M, 946684800)] r=[timefmt($r, 946684800)]).;
@log smoke=TC004: timefmt invalid secs. Failed (inv=[timefmt($A\, $B $d\, $Y\, $I:$M $p,#-1 INVALID DATE)] nan=[timefmt($Y, not-a-number)] xyz=[timefmt($Y, xyzzy)]).;
@trig me/tr.done
}
-