Issue below was AI-generated, the introduction has been hand-edited
vcal.parse_ical() was added to handle CalDAV-noise before it would
cause a ValueError exception coming from the icalendar library.
The "CalDAV-noise" can be a body with no iCalendar in it - an empty
scheduling-inbox object, an HTML error page delivered with a 200, a
notification carrying only headers, etc. parse_ical() raises
error.ResponseError instead, quoting what arrived and the URL where
one is known.
It is currently used at four of the parse sites, and there are others that still
hand data to the parser directly. Anything that can be fed by a server should go
through the guard, so the error is the same everywhere.
Sites still parsing directly
caldav/jmap/objects/calendar_object.py:64 -
icalendar.Calendar.from_ical(jscal_to_ical(self.data)). Server-fed: self.data
is JSCalendar from a JMAP response, so a server that returns something
unconvertible lands here. This is the one that matters.
caldav/datastate.py:140, :192, :228 and
caldav/calendarobjectresource.py:1612 - vobject.readOne(...). Same data,
different parser, same problem: an empty body gives a vobject error that says
nothing about where it came from. A parse_vobject() counterpart, or one guard
the two share, would cover it.
caldav/lib/vcal.py:243 (inside create_ical()) and
caldav/jmap/convert/ical_to_jscal.py:306 - both parse iCalendar the caller
supplied, not a server response. Arguably these should keep raising whatever
icalendar raises, since a broken fragment there is a client-side bug, not a
server one. Worth deciding explicitly rather than by omission.
Points worth deciding
- Should the guard fire on the JSCalendar side too - a JMAP response that
converts to no components at all - or only once it has become iCalendar?
parse_ical() is deliberately narrow: it fires only when the body holds no
BEGIN: line, and hands anything containing a component to icalendar unchanged.
That boundary should stay wherever it is applied, so that a genuinely malformed
calendar is not reclassified as a server error.
- A test that walks the module tree and fails on a bare
icalendar.Calendar.from_ical( / vobject.readOne( outside the guard would keep
this from drifting back. Cheap, and the kind of rule that only holds if it is
enforced.
Issue below was AI-generated, the introduction has been hand-edited
vcal.parse_ical()was added to handle CalDAV-noise before it wouldcause a
ValueErrorexception coming from theicalendarlibrary.The "CalDAV-noise" can be a body with no iCalendar in it - an empty
scheduling-inbox object, an HTML error page delivered with a 200, a
notification carrying only headers, etc.
parse_ical()raiseserror.ResponseErrorinstead, quoting what arrived and the URL whereone is known.
It is currently used at four of the parse sites, and there are others that still
hand data to the parser directly. Anything that can be fed by a server should go
through the guard, so the error is the same everywhere.
Sites still parsing directly
caldav/jmap/objects/calendar_object.py:64-icalendar.Calendar.from_ical(jscal_to_ical(self.data)). Server-fed:self.datais JSCalendar from a JMAP response, so a server that returns something
unconvertible lands here. This is the one that matters.
caldav/datastate.py:140,:192,:228andcaldav/calendarobjectresource.py:1612-vobject.readOne(...). Same data,different parser, same problem: an empty body gives a vobject error that says
nothing about where it came from. A
parse_vobject()counterpart, or one guardthe two share, would cover it.
caldav/lib/vcal.py:243(insidecreate_ical()) andcaldav/jmap/convert/ical_to_jscal.py:306- both parse iCalendar the callersupplied, not a server response. Arguably these should keep raising whatever
icalendar raises, since a broken fragment there is a client-side bug, not a
server one. Worth deciding explicitly rather than by omission.
Points worth deciding
converts to no components at all - or only once it has become iCalendar?
parse_ical()is deliberately narrow: it fires only when the body holds noBEGIN:line, and hands anything containing a component to icalendar unchanged.That boundary should stay wherever it is applied, so that a genuinely malformed
calendar is not reclassified as a server error.
icalendar.Calendar.from_ical(/vobject.readOne(outside the guard would keepthis from drifting back. Cheap, and the kind of rule that only holds if it is
enforced.