diff --git a/radicale/__init__.py b/radicale/__init__.py index e34222d5..3e711c75 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -814,7 +814,10 @@ class Application: return PRECONDITION_FAILED try: - items = list(vobject.readComponents(content or "")) + items = tuple(vobject.readComponents(content or "")) + if not write_whole_collection and len(items) != 1: + raise RuntimeError( + "Content contains %d components" % len(items)) for i in items: storage.check_and_sanitize_item( i, is_collection=write_whole_collection, uid=item.uid diff --git a/radicale/storage.py b/radicale/storage.py index 3a2dd6d5..7911bb7c 100644 --- a/radicale/storage.py +++ b/radicale/storage.py @@ -362,7 +362,11 @@ class Item: def item(self): if self._item is None: try: - self._item = vobject.readOne(self._text) + items = tuple(vobject.readComponents(self._text)) + if len(items) != 1: + raise RuntimeError( + "Content contains %d components" % len(items)) + self._item = items[0] except Exception as e: raise RuntimeError("Failed to parse item %r from %r: %s" % (self.href, self.collection.path, e)) from e