Fix/caldav option forgiving#62090
Conversation
a4141cf to
dc5b8d5
Compare
| private function getReaderOptions(): int { | ||
| return $this->config->getSystemValueBool('dav.forgiving_ical_parser', false) | ||
| ? Reader::OPTION_FORGIVING | ||
| : 0; | ||
| } | ||
| } |
There was a problem hiding this comment.
This should be an import option, not a system configuration value
There was a problem hiding this comment.
Okay, that makes sense, ImportOption is a better approach for andling the ImportService code path, but what about the main problem this PR is addressing, i.e., if I get the non-standard ICS from CalDAV PUT which goes through Plugin::validateICalendar?
Should the IConfig be used for that though?
There was a problem hiding this comment.
We'll the issue you linked specifically states that the issue is with importing. Not with general PUT requests from a specific client, so I would not add a plugin to validate the events.
Also there is a PR that will fix a lot of this in the future.
|
|
||
| $calendarObjects = array_map(function ($o) use ($options) { | ||
| $calendarData = Reader::read($o['calendardata']); | ||
| $calendarData = Reader::read($o['calendardata'], $this->getReaderOptions()); |
There was a problem hiding this comment.
This is not needed, once the data is read the first time with the forgiving flag, it should not need to be read with this flag.
| */ | ||
| public function getDenormalizedData(string $calendarData): array { | ||
| $vObject = Reader::read($calendarData); | ||
| $vObject = Reader::read($calendarData, $this->getReaderOptions()); |
| @@ -3843,7 +3843,13 @@ public function moveCalendar($uriName, $uriOrigin, $uriDestination, $newUriName | |||
| * @return VCalendar | |||
| */ | |||
| protected function readCalendarData($objectData) { | |||
| $vObject->add(clone $timezones[$zone]); | ||
| } | ||
| } | ||
| yield $vObject; |
There was a problem hiding this comment.
In general, once the object is read, once, the correct object exists and is serialized back to a proper object, it should not need to be run using the flag.
There was a problem hiding this comment.
Fair enough, I should have referred to case #45574 as the main issue instead of #16679 (I just updated the description to reflect this.).
For me, the main problem is that my users receive non-standard ICS invites by email (usually coming from Outlook) and hence the PR.
Fixing the import seemed like a logical thing to do as well, but perhaps I should drop this and open a new PR that addresees just this `CalDAV PUT' and case #45574.
There was a problem hiding this comment.
Event updates are not handled by any of the code in this PR. so this would not fix your issue.
Also the most likely issue with Outook invitations is a missing Organizer property. which I already made a work around for.
Can you share one of the non working invitations with me?
There was a problem hiding this comment.
I attached an ICS file that gives 415 Unsupported Media Type error when CalDAV PUT is done against master and 201 Created when done against fix/caldav-option-forgiving.
See also the transcript in https://gist.github.com/tlilja/2b3f7a26c816d730cd0d6a260cc77809
There was a problem hiding this comment.
Okay, I see the issue the "X-ENTOURAGE_UUID" property has a underscore.
How is the CalDav put done? A import?
There was a problem hiding this comment.
I believe the CalDAV PUT handling is done by apps/dav/lib/CalDav/Plugin.php, specifically VObject\Reader::read() call in Plugin.php:65 in this PR.
So the code path is different from Import which, though, invokes the same VObject\Reader::read().
There was a problem hiding this comment.
That code in Plugin.php is the validation only.
The actual storing/updating the calendar events to the database is done by two CalDavBackend methods createCalendarObject() and updateCalendarObject() in apps/dav/lib/CalDav/CalDavBackend.php.
…g_ical_parser is set Clients such as Outlook for Mac produce property names with underscores (e.g. X-ENTOURAGE_UUID), which are invalid per RFC 5545 §3.2 and cause sabre to throw a ParseException, resulting in a 415 response. When the system config key dav.forgiving_ical_parser is true, pass Sabre\VObject\Reader::OPTION_FORGIVING to every Reader::read() call site in the CalDAV stack (Plugin::validateICalendar, CalDavBackend, ImportService). Non-conforming property names are then silently ignored rather than rejected. Assisted-by: ClaudeCode:claude-sonnet-4-6 Signed-off-by: Timo Lilja <timo.lilja@iki.fi>
…d and ImportService Assisted-by: ClaudeCode:claude-sonnet-4-6 Signed-off-by: Timo Lilja <timo.lilja@iki.fi>
dc5b8d5 to
28f91d2
Compare
Parse error: Invalid Mimedir file#45574Processing message failed. Status: 80004005.#17915Summary
This is a self-contained PR that adds support for using SabreDAV's
OPTION_FORGIVINGwhendav.forigiving_ical_parserconfig option is set to allow non-standard ICS events parsed instead of giving error.For example, Outlook on Mac, under certain conditions, generates ICS events that have invalid key
X-ENTOURAGE_UID(underscore should be dash) which get rejected by Nextcloud/SabreDAV's strict parser by default.This PR requires no changes to SabreDAV unlike the closed PR nextcloud/3rdparty#902 which got subsequently pushed to SabreDAV (sabre-io/dav#1563)
This PR includes unit tests and all DAV tests pass with the changes.
A bit problematic part of this PR is that overriding
\Sabre\CalDAV\Plugin::validateICalendar()just to replace theVObject\Reader::read()call which is prone to error if SabreDAV changes theirvalidateICalendar(). A better approach would be to refactor\Sabre\CalDAV\Pluginto allow overriding only theVObject\Reader::read()invocationa arguments with a hook but that would require changes on SabreDAV side whereas this is fully self-contained to Nextcloud.TODO
Checklist
3. to review, feature component)stable32)AI (if applicable)