diff --git a/tests/storage/dav/test_main.py b/tests/storage/dav/test_main.py index e48d5d5..1ac356f 100644 --- a/tests/storage/dav/test_main.py +++ b/tests/storage/dav/test_main.py @@ -13,7 +13,7 @@ from tests import EVENT_TEMPLATE, TASK_TEMPLATE, VCARD_TEMPLATE import vdirsyncer.exceptions as exceptions from vdirsyncer.storage.base import Item -from vdirsyncer.storage.dav import CaldavStorage, CarddavStorage +from vdirsyncer.storage.dav import CaldavStorage, CarddavStorage, _parse_xml from .. import StorageTests, format_item @@ -183,3 +183,10 @@ class TestCarddavStorage(DavStorageTests): @pytest.fixture(params=['VCARD']) def item_type(self, request): return request.param + + +def test_broken_xml(capsys): + rv = _parse_xml(b'

\x10haha

') + assert rv.text == 'haha' + warnings = capsys.readouterr()[1] + assert 'partially invalid xml' in warnings.lower() diff --git a/vdirsyncer/storage/dav.py b/vdirsyncer/storage/dav.py index a5136ed..640c062 100644 --- a/vdirsyncer/storage/dav.py +++ b/vdirsyncer/storage/dav.py @@ -42,12 +42,18 @@ class InvalidXMLResponse(exceptions.InvalidResponse): def _parse_xml(content): - try: - return etree.XML(content) - except etree.Error as e: + p = etree.XMLParser(recover=True) + rv = etree.XML(content, parser=p) + if rv is None: raise InvalidXMLResponse('Invalid XML encountered: {}\n' 'Double-check the URLs in your config.' - .format(e)) + .format(p.error_log)) + if p.error_log: + dav_logger.warning('Partially invalid XML response, some of your ' + 'items may be corrupted. Check the debug log and ' + 'consider switching servers. ({})' + .format(p.error_log)) + return rv def _merge_xml(items):