From 12871fdcb38acbb49aa65339d38c54873d611993 Mon Sep 17 00:00:00 2001 From: Unrud Date: Fri, 9 Jun 2017 02:30:51 +0200 Subject: [PATCH] Workaround for bugs in VObject during filtering --- radicale/storage.py | 15 +++++++++++++-- radicale/xmlutils.py | 25 +++++++++++++++++-------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/radicale/storage.py b/radicale/storage.py index e3b6f1df..2c0e61f5 100644 --- a/radicale/storage.py +++ b/radicale/storage.py @@ -1034,8 +1034,19 @@ class Collection(BaseCollection): ctext = vobject_item.serialize() cetag = get_etag(ctext) try: - ctag, cstart, cend = xmlutils.find_tag_and_time_range( - vobject_item) + try: + ctag, cstart, cend = xmlutils.find_tag_and_time_range( + vobject_item) + except xmlutils.VObjectBugException as e: + # HACK: Extraction of metadata failed, because of bugs in + # VObject. + self.logger.warning( + "Failed to find tag and time range of item %r from %r " + "(Bug in VObject): %s", href, self.path, e, + exc_info=True) + ctag = xmlutils.find_tag(vobject_item) + cstart = xmlutils.TIMESTAMP_MIN + cend = xmlutils.TIMESTAMP_MAX except Exception as e: raise RuntimeError("Failed to find tag and time range of item " "%r from %r: %s" % (href, self.path, diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index 9d7ba917..b19a1e72 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -579,6 +579,15 @@ def simplify_prefilters(filters): return None, TIMESTAMP_MIN, TIMESTAMP_MAX, simple +def find_tag(vobject_item): + """Find tag from ``vobject_item``.""" + if vobject_item.name == "VCALENDAR": + for component in vobject_item.components(): + if component.name in ("VTODO", "VEVENT", "VJOURNAL"): + return component.name + return None + + def find_tag_and_time_range(vobject_item): """Find tag and enclosing time range from ``vobject item``. @@ -588,15 +597,9 @@ def find_tag_and_time_range(vobject_item): This is intened to be used for matching against simplified prefilters. """ - tag = "" - if vobject_item.name == "VCALENDAR": - for component in vobject_item.components(): - if component.name in ("VTODO", "VEVENT", "VJOURNAL"): - tag = component.name - break + tag = find_tag(vobject_item) if not tag: - return (None, math.floor(DATETIME_MIN.timestamp()), - math.ceil(DATETIME_MAX.timestamp())) + return (None, TIMESTAMP_MIN, TIMESTAMP_MAX) start = end = None def range_fn(range_start, range_end): @@ -1136,6 +1139,12 @@ def report(base_prefix, path, xml_request, collection): if not all(match(item, filter_[0]) for filter_ in filters if filter_): continue + except VObjectBugException as e: + # HACK: Just return all items that can't be filtered because + # of bugs in VObject. + collection.logger.warning( + "Failed to filter item %r from %r (Bug in VObject): %s", + item.href, collection.path, e, exc_info=True) except Exception as e: raise RuntimeError("Failed to filter item %r from %r: %s" % (item.href, collection.path, e)) from e