From 44f538295c25a95abe146d64cecc321432170722 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Wed, 21 Feb 2024 12:28:11 -0500 Subject: [PATCH] Try new strategy for CalDAV report filter parsing. The recursive strategy I initially built looked clever but it's not going to work because we need to iterate through both the rules and the components/properties/parameters at the same time. Reworked the code to go through filters iteratively instead of recursively. This protocol is way too complex and the people who designed it need to be tortured. --- webcit-ng/server/caldav_reports.c | 109 ++++++++++++------------------ webcit-ng/server/webcit.h | 2 +- 2 files changed, 44 insertions(+), 67 deletions(-) diff --git a/webcit-ng/server/caldav_reports.c b/webcit-ng/server/caldav_reports.c index 31fe712ba..05d3b9ef6 100644 --- a/webcit-ng/server/caldav_reports.c +++ b/webcit-ng/server/caldav_reports.c @@ -4,9 +4,8 @@ #include "webcit.h" -// Shorthand for the XML namespace of CalDAV -#define CAL "urn:ietf:params:xml:ns:caldav:" -#define CALLEN sizeof(CAL)-1 +#define CAL "urn:ietf:params:xml:ns:caldav:" // Shorthand for the XML namespace of CalDAV +#define CALLEN sizeof(CAL)-1 // And the length of that string // A CalDAV REPORT can only be one type. This is stored in the report_type member. enum cr_type { @@ -273,78 +272,56 @@ void caldav_report_one_item(struct http_transaction *h, struct ctdlsession *c, S } -// Called by caldav_apply_filters() to apply ONE filter. -// Returns 0 if the calendar item does not match the filter. -// Returns 1 if the calendar item DOES match the filter. -int caldav_apply_one_filter(void *cal, char *filter) { - syslog(LOG_DEBUG, "applying filter: %s", filter); - - char this_filter[SIZ]; // we have to copy the filter string because we will destructively tokenize it - safestrncpy(this_filter, filter, sizeof(this_filter)); - - char *t[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } ; - char *f = this_filter; - int num_tokens = 0; - while ( (t[num_tokens]=strtok_r(f, "|", &f)) && (num_tokens<10) ) { - ++num_tokens; - } - - // BEGIN experimental block -- see what happens when we cast to the wrong type - - //icalcomponent *foo_comp = (icalcomponent *) cal; - //icalproperty *foo_prop = (icalproperty *) cal; - //icalparameter *foo_param = (icalparameter *) cal; - - // END experimental block - - // Handle the individual filters defined in RFC4791 9.7.1 through 9.7.5 - - if (!strcasecmp(t[1], "comp-filter")) { // RFC4791 9.7.1 - filter by component - syslog(LOG_DEBUG, "component filter FIXME not implemented yet"); - if (icalcomponent_isa_component(cal)) { - syslog(LOG_DEBUG, "\033[32m yes this is a component \033[0m"); - } - else { - syslog(LOG_DEBUG, "\033[31m no this is not a component \033[0m"); +// Recursive function to apply CalDAV FILTERS to a calendar item. +// Returns zero if the calendar item was disqualified by a filter, nonzero if the calendar item still qualifies. +int caldav_apply_filters(void *cal, Array *filters) { + + int f = 0; // filter number iterator + int qual = 1; // 0 for disqualify, 1 for qualify + + while ( (f