From f39f6af06a3979e7dab6420683a1cdc7a95d1fac Mon Sep 17 00:00:00 2001 From: Andrew McMillan Date: Mon, 27 Aug 2007 20:27:42 +1200 Subject: [PATCH] Fix bug in query with empty component filter, and add regression test for that. --- inc/caldav-REPORT-calquery.php | 41 +++-- .../231-Moz-REPORT-All-Tasks.result | 150 ++++++++++++++++++ .../231-Moz-REPORT-All-Tasks.test | 32 ++++ 3 files changed, 210 insertions(+), 13 deletions(-) create mode 100644 testing/tests/regression-suite/231-Moz-REPORT-All-Tasks.result create mode 100644 testing/tests/regression-suite/231-Moz-REPORT-All-Tasks.test diff --git a/inc/caldav-REPORT-calquery.php b/inc/caldav-REPORT-calquery.php index b4b7c2d1..32ef3388 100644 --- a/inc/caldav-REPORT-calquery.php +++ b/inc/caldav-REPORT-calquery.php @@ -31,9 +31,19 @@ switch( $proptype ) { * the case and leave it alone otherwise. */ $qry_filters = $xmltree->GetPath('/URN:IETF:PARAMS:XML:NS:CALDAV:CALENDAR-QUERY/URN:IETF:PARAMS:XML:NS:CALDAV:FILTER/*'); -$qry_filters = $qry_filters[0]; // There can only be one FILTER element -if ( $qry_filters->GetTag() == "URN:IETF:PARAMS:XML:NS:CALDAV:COMP-FILTER" && $qry_filters->GetAttribute("NAME") == "VCALENDAR" ) - $qry_filters = $qry_filters->GetContent(); // Everything is inside a VCALENDAR AFAICS +if ( count($qry_filters) == 1 ) { + $qry_filters = $qry_filters[0]; // There can only be one FILTER element + if ( $qry_filters->GetTag() == "URN:IETF:PARAMS:XML:NS:CALDAV:COMP-FILTER" && $qry_filters->GetAttribute("NAME") == "VCALENDAR" ) + $qry_filters = $qry_filters->GetContent(); // Everything is inside a VCALENDAR AFAICS + else { + dbg_error_log("calquery", "Got bizarre CALDAV:FILTER[%s=%s]] which does not contain COMP-FILTER = VCALENDAR!!", $qry_filters->GetTag(), $qry_filters->GetAttribute("NAME") ); + $qry_filters = false; + } +} +else { + $qry_filters = false; +} + /** * While we can construct our SQL to apply some filters in the query, other filters @@ -49,7 +59,7 @@ function apply_filter( $filters, $item ) { if ( count($filters) == 0 ) return true; - dbg_error_log("REPORT","Applying filter for item '%s'", $item->dav_name ); + dbg_error_log("calquery","Applying filter for item '%s'", $item->dav_name ); $ical = new iCalendar( array( "icalendar" => $item->caldav_data) ); return $ical->TestFilter($filters); } @@ -63,12 +73,12 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter = global $need_post_filter; $sql = ""; if ( !is_array($filter) ) { - dbg_error_log( "REPORT", "Filter is of type '%s', but should be an array of XML Tags.", gettype($filter) ); + dbg_error_log( "calquery", "Filter is of type '%s', but should be an array of XML Tags.", gettype($filter) ); } foreach( $filter AS $k => $v ) { $tag = $v->GetTag(); - dbg_error_log("REPORT", "Processing $tag into SQL - %d, '%s', %d\n", count($components), $property, isset($parameter) ); + dbg_error_log("calquery", "Processing $tag into SQL - %d, '%s', %d\n", count($components), $property, isset($parameter) ); $not_defined = ""; switch( $tag ) { @@ -77,7 +87,7 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter = case 'URN:IETF:PARAMS:XML:NS:CALDAV:IS-DEFINED': if ( isset( $parameter ) ) { $need_post_filter = true; - dbg_error_log("REPORT", "Could not handle IS-%sDEFINED on property %s, parameter %s in SQL", $not_defined, $property, $parameter ); + dbg_error_log("calquery", "Could not handle IS-%sDEFINED on property %s, parameter %s in SQL", $not_defined, $property, $parameter ); return false; // Not handled in SQL } if ( isset( $property ) ) { @@ -142,8 +152,10 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter = } $components[] = $comp_filter_name; $subfilter = $v->GetContent(); - $success = SqlFilterFragment( $subfilter, $components, $property, $parameter ); - if ( $success === false ) continue; else $sql .= $success; + if ( is_array( $subfilter ) ) { + $success = SqlFilterFragment( $subfilter, $components, $property, $parameter ); + if ( $success === false ) continue; else $sql .= $success; + } break; case 'URN:IETF:PARAMS:XML:NS:CALDAV:PROP-FILTER': @@ -174,7 +186,7 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter = case 'COMPLETED': /** TODO: this should be moved into the properties supported in SQL. */ default: $need_post_filter = true; - dbg_error_log("REPORT", "Could not handle PROP-FILTER on %s in SQL", $propertyname ); + dbg_error_log("calquery", "Could not handle PROP-FILTER on %s in SQL", $propertyname ); return false; // Can't handle PROP-FILTER conditions in the SQL for this property } $subfilter = $v->GetContent(); @@ -192,7 +204,7 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter = break; } } - dbg_error_log("REPORT", "Generated SQL was '%s'", $sql ); + dbg_error_log("calquery", "Generated SQL was '%s'", $sql ); return $sql; } @@ -219,14 +231,17 @@ function BuildSqlFilter( $filter ) { $responses = array(); $where = " WHERE caldav_data.dav_name ~ ".qpg("^".$request->path)." "; -$where .= BuildSqlFilter( $qry_filters); +if ( is_array($qry_filters) ) { + dbg_log_array( "calquery", "qry_filters", $qry_filters, true ); + $where .= BuildSqlFilter( $qry_filters ); +} $where .= "AND (calendar_item.class != 'PRIVATE' OR calendar_item.class IS NULL OR get_permissions($session->user_no,caldav_data.user_no) ~ 'A') "; // Must have 'all' permissions to see confidential items if ( isset($c->hide_TODO) && $c->hide_TODO ) { $where .= "AND (caldav_data.caldav_type NOT IN ('VTODO') OR get_permissions($session->user_no,caldav_data.user_no) ~ 'A') "; } $qry = new PgQuery( "SELECT * , get_permissions($session->user_no,caldav_data.user_no) as permissions FROM caldav_data INNER JOIN calendar_item USING(user_no, dav_name)". $where ); -if ( $qry->Exec("REPORT",__LINE__,__FILE__) && $qry->rows > 0 ) { +if ( $qry->Exec("calquery",__LINE__,__FILE__) && $qry->rows > 0 ) { while( $calendar_object = $qry->Fetch() ) { if ( !$need_post_filter || apply_filter( $qry_filters, $calendar_object ) ) { $responses[] = calendar_to_xml( $properties, $calendar_object ); diff --git a/testing/tests/regression-suite/231-Moz-REPORT-All-Tasks.result b/testing/tests/regression-suite/231-Moz-REPORT-All-Tasks.result new file mode 100644 index 00000000..fb9fbe69 --- /dev/null +++ b/testing/tests/regression-suite/231-Moz-REPORT-All-Tasks.result @@ -0,0 +1,150 @@ +HTTP/1.1 207 Multi-Status +Date: Dow, 01 Jan 2000 00:00:00 GMT +ETag: "5c9f342ddba9b5c267dac8ad62586abe" +Content-Length: 4276 +Content-Type: text/xml; charset="utf-8" + + + + + http://myapms/calendar/caldav.php/user1/home/2178279a-aec2-471f-832d-1f6df6203f2f.ics + + + "509b0f0d8a3363379f9f5727f5dd74a0" + BEGIN:VCALENDAR +PRODID:-//Mozilla Calendar//NONSGML Sunbird//EN +VERSION:2.0 +BEGIN:VTODO +CREATED:20070805T200215Z +LAST-MODIFIED:20070805T201531Z +DTSTAMP:20070805T200215Z +UID:2178279a-aec2-471f-832d-1f6df6203f2f +SUMMARY:Incomplete\, uncancelled +X-MOZ-LOCATIONPATH:2178279a-aec2-471f-832d-1f6df6203f2f.ics +DESCRIPTION:This task is incomplete and has not been cancelled (has no + status at all) +END:VTODO +END:VCALENDAR + + + HTTP/1.1 200 OK + + + + http://myapms/calendar/caldav.php/user1/home/917b9e47-b748-4550-a566-657fbe672447.ics + + + "cb3d9dc3e8c157f53eba3ea0e1e0f146" + BEGIN:VCALENDAR +PRODID:-//Mozilla Calendar//NONSGML Sunbird//EN +VERSION:2.0 +BEGIN:VTODO +CREATED:20070805T201557Z +LAST-MODIFIED:20070805T201643Z +DTSTAMP:20070805T201557Z +UID:917b9e47-b748-4550-a566-657fbe672447 +SUMMARY:50% Complete\, uncancelled +STATUS:IN-PROCESS +PERCENT-COMPLETE:50 +X-MOZ-LOCATIONPATH:917b9e47-b748-4550-a566-657fbe672447.ics +DESCRIPTION:This task is in progress (50% complete) and has not been + cancelled. +END:VTODO +END:VCALENDAR + + + HTTP/1.1 200 OK + + + + http://myapms/calendar/caldav.php/user1/home/0575d895-a006-4ed8-9be6-0d1b6b6b1f96.ics + + + "00ad5eb1eb5507884710b0b66aa5d5c4" + BEGIN:VCALENDAR +PRODID:-//Mozilla Calendar//NONSGML Sunbird//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:/mozilla.org/20070129_1/Antarctica/McMurdo +X-LIC-LOCATION:Antarctica/McMurdo +BEGIN:STANDARD +TZOFFSETFROM:+1300 +TZOFFSETTO:+1200 +TZNAME:NZST +DTSTART:19700315T030000 +RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=3SU;BYMONTH=3 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+1200 +TZOFFSETTO:+1300 +TZNAME:NZDT +DTSTART:19701004T020000 +RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=10 +END:DAYLIGHT +END:VTIMEZONE +BEGIN:VTODO +CREATED:20070805T201647Z +LAST-MODIFIED:20070805T201834Z +DTSTAMP:20070805T201647Z +UID:0575d895-a006-4ed8-9be6-0d1b6b6b1f96 +SUMMARY:Due 7/8/7 16:30\, completed +STATUS:COMPLETED +DUE;TZID=/mozilla.org/20070129_1/Antarctica/McMurdo:20070807T163000 +COMPLETED:20070805T201737Z +PERCENT-COMPLETE:100 +X-MOZ-LOCATIONPATH:0575d895-a006-4ed8-9be6-0d1b6b6b1f96.ics +DESCRIPTION:Due on 7/8/7 at 4:30pm\, but completed alread on 6/8/7 +CATEGORIES:Projects +END:VTODO +END:VCALENDAR + + + HTTP/1.1 200 OK + + + + http://myapms/calendar/caldav.php/user1/home/b1679f77-673d-4f46-b3eb-2420e1bba301.ics + + + "a2990674708634a311bb98a59865ca50" + BEGIN:VCALENDAR +PRODID:-//Mozilla Calendar//NONSGML Sunbird//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:/mozilla.org/20070129_1/Antarctica/McMurdo +X-LIC-LOCATION:Antarctica/McMurdo +BEGIN:STANDARD +TZOFFSETFROM:+1300 +TZOFFSETTO:+1200 +TZNAME:NZST +DTSTART:19700315T030000 +RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=3SU;BYMONTH=3 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+1200 +TZOFFSETTO:+1300 +TZNAME:NZDT +DTSTART:19701004T020000 +RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=10 +END:DAYLIGHT +END:VTIMEZONE +BEGIN:VTODO +CREATED:20070806T223244Z +LAST-MODIFIED:20070806T223411Z +DTSTAMP:20070806T223244Z +UID:b1679f77-673d-4f46-b3eb-2420e1bba301 +SUMMARY:A Cancelled Task\, with a start and due date +STATUS:CANCELLED +DTSTART;TZID=/mozilla.org/20070129_1/Antarctica/McMurdo:20070808T111500 +DUE;TZID=/mozilla.org/20070129_1/Antarctica/McMurdo:20070808T111500 +X-MOZ-LOCATIONPATH:b1679f77-673d-4f46-b3eb-2420e1bba301.ics +DESCRIPTION:This is a task with a Start and a Due date\, but it has been + cancelled. +END:VTODO +END:VCALENDAR + + + HTTP/1.1 200 OK + + + diff --git a/testing/tests/regression-suite/231-Moz-REPORT-All-Tasks.test b/testing/tests/regression-suite/231-Moz-REPORT-All-Tasks.test new file mode 100644 index 00000000..56258a16 --- /dev/null +++ b/testing/tests/regression-suite/231-Moz-REPORT-All-Tasks.test @@ -0,0 +1,32 @@ +# +# Do a REPORT request (test operation in subdirectory of unrelated site) +# +TYPE=REPORT +URL=http://myapms/calendar/caldav.php/user1/home/ +HEAD + +HEADER=User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.7) Gecko/20061013 Thunderbird/1.5.0.7 +HEADER=Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 +HEADER=Accept-Language: en-us,en;q=0.5 +HEADER=Accept-Encoding: gzip,deflate +HEADER=Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 +HEADER=Content-Type: text/xml +HEADER=Depth: 1 + + + +BEGINDATA + + + + + + + + + + + + +ENDDATA +