Menu

#2082 `DATE` accepts day-of-year 0 and then reads `monthNames[-1]`, segfaulting on output style `M`

5.3.0
open
nobody
None
none
5
2026-08-22
2026-08-22
No
say date('M','0','D')

exits with SIGSEGV, rc 139, printing nothing. Measured deterministic, three runs of three.

The day-of-year range check in RexxBuiltinFunctionDATE
(interpreter/expression/BuiltinFunctions.cpp:1163) reads
yearday < 0 || yearday > YEAR_DAYS + 1 || .... Day zero is one below the first valid day, but the
check only rejects strictly negative values, so 0 passes. RexxDateTime::setDay
(interpreter/classes/support/RexxDateTime.cpp:457-475) then computes month = 0 from a zero day
count, and the M output style reads monthNames[month - 1] at RexxDateTime.cpp:526 -- that is
monthNames[-1], one element before the array, whose bytes form an invalid pointer that the
subsequent string read dereferences.

The other output styles reachable from the same month == 0 state do not crash, and the contrast is
what identifies the faulting read: D, B, W, F and T read monthStarts[-1], which on this
build holds 0, so they return stable but wrong values (D gives 0, B gives 739615, W gives
Wednesday, F gives 63902736000000000, T gives 1767139200). M is the only style whose
out-of-bounds read is dereferenced as a pointer rather than used as an integer.

The fix is presumably to reject yearday < 1 rather than yearday < 0, but note that the other five
styles are silently wrong on the same input today, so a range-check fix changes their answers too.

Not a duplicate of #1729, which is invalid and concerns the documented digit limits of the second
argument.

Discussion

Anonymous
Anonymous

Add attachments
Cancel