Calendar and report: a date at the edge of the calendar, or a five-digit quarter year, answers 500 #389
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#389
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-09-29 in a read-only review of postulo at
95348908d, reading how the calendar and the report read a period from the address, and running the period helpers with extreme values.Checked again on 2026-10-01 against
mainat0a5cad587: still present. The code is now atapplications/agenda.py:513-524(month_fromandday_from),:436-442(next_monthandprevious_month),:630(week view),:647(day view) and:662(agenda view), and the report views are atapplications/views.py:1147-1150,:1178(CSV) and:1207(PDF);applications/reports.pyandapplications/slow.pyare unchanged. Run again on that code, every address and helper call listed below still raised.Both pages promise that an address somebody edited by hand gets a sensible page rather than an error:
page_for's docstring says a mistyped address "still gets a calendar rather than an error about dates", andperiod_from's says "Nothing here refuses". The parsers do fall back on text they cannot read, but they accept any yeardatetimeaccepts, and the code then steps one period past it or builds a date from an unchecked year.OverflowErrororValueErrorescapes and the page answers 500.applications/agenda.py:440-451,month_fromandday_from: accept 0001 to 9999.applications/agenda.py:364-371,next_monthandprevious_month: step past 9999-12 and 0001-01;:552(week view),:569(day view) and:584(agenda view) add days past 9999-12-31.applications/reports.py:188-196,_intand_date, andperiod_fromat:211-217: forperiod=quarter&on=<year>-Q<n>, the year is any integer, andquarter_period(:156) callsdt.date(year, …)with it.applications/reports.py:134-148,Period.shifted: the view (applications/views.py:1107-1110) always asks for the period before and after, which leaves the range for 0001-01 and 9999-12.applications/reports.py:304(_cadence) and:439(build, viaPeriod.bounds) overflow for a custom range in December 9999.period_fromfollowed byshifted(-1),shifted(1)andbounds()raised for every one ofperiod=month&on=9999-12,period=month&on=0001-01,period=quarter&on=9999-Q4,period=quarter&on=99999-Q1,period=quarter&on=0-Q1andperiod=custom&from=9999-12-01&to=9999-12-31;agenda.month_range(date(9999, 12, 1))andagenda.previous_month(date(1, 1, 1))raisedOverflowError. The quarter case is the likeliest to be met: a year typed with one digit too many (20266-Q3) reachesdt.date(20266, 7, 1)insideperiod_fromitself. The sameperiod_fromruns in thereport_pdferrand (applications/slow.py:32), and in the CSV and PDF views (applications/views.py:1138and:1167).month_from,day_fromandreports._datereturnNoneoutside a sane range (for example years 1900 to 2200), and have the quarter branch ofperiod_fromtreat a year outside that range as unreadable and fall back totoday.year. The pages then fall back to today as their docstrings say.Done when
tests/test_calendar.pyrequests?month=0001-01,?month=9999-12and?view=day&on=9999-12-31and gets 200.tests/test_reports.pyrequestsperiod=month&on=9999-12,period=quarter&on=20266-Q3andperiod=custom&from=9999-12-01&to=9999-12-31, and each answers 200 with the fallback period.