Browse Source

improved detection of broken vcards

Peter Bieringer 9 years ago
parent
commit
af5c1582dc
2 changed files with 24 additions and 4 deletions
  1. 13 1
      radicale/storage.py
  2. 11 3
      radicale/xmlutils.py

+ 13 - 1
radicale/storage.py

@@ -715,9 +715,21 @@ class Collection(BaseCollection):
                 self.logger.debug("Read object: %s", path)
                 with open(path, encoding=self.encoding, newline="") as fd:
                     try:
-                        items.append(vobject.readOne(fd.read()))
+                        # check whether vobject liks the item
+                        item = vobject.readOne(fd.read())
                     except:
                         self.logger.exception("Object broken (skip 'list'): %s", path)
+                        continue
+
+                    if self.get_meta("tag") == "VADDRESSBOOK":
+                        try:
+                            # check whether vobject liks the VCARD item
+                            item.serialize()
+                        except:
+                            self.logger.exception("Object broken (skip 'read'): %s", path)
+                            self.logger.error("Broken VCARD content: %s", item)
+                            continue
+                    items.append(item)
         time_end = datetime.datetime.now()
         self.logger.info("Collection read %d items in %s sec from %s", len(items),(time_end - time_begin).total_seconds(), self._filesystem_path)
         if self.get_meta("tag") == "VCALENDAR":

+ 11 - 3
radicale/xmlutils.py

@@ -28,6 +28,7 @@ in them for XML requests (all but PUT).
 import posixpath
 import re
 import xml.etree.ElementTree as ET
+from pprint import pprint
 from collections import OrderedDict
 from datetime import datetime, timedelta, timezone
 from http import client
@@ -523,13 +524,15 @@ def propfind(path, xml_request, read_collections, write_collections, user):
         collections.append(collection)
         response = _propfind_response(
             path, collection, props, user, write=True)
-        multistatus.append(response)
+        if response:
+            multistatus.append(response)
     for collection in read_collections:
         if collection in collections:
             continue
         response = _propfind_response(
             path, collection, props, user, write=False)
-        multistatus.append(response)
+        if response:
+            multistatus.append(response)
 
     return client.MULTI_STATUS, _pretty_xml(multistatus)
 
@@ -569,7 +572,12 @@ def _propfind_response(path, item, props, user, write=False):
         element = ET.Element(tag)
         is404 = False
         if tag == _tag("D", "getetag"):
-            element.text = item.etag
+            try:
+                element.text = item.etag
+            except:
+                print("Object broken (skip)")
+                pprint(vars(item))
+                return None
         elif tag == _tag("D", "getlastmodified"):
             element.text = item.last_modified
         elif tag == _tag("D", "principal-collection-set"):