Merge pull request #1971 from pbiering/fix-issue-1970

Support issue 1970
This commit is contained in:
Peter Bieringer
2026-01-22 21:58:44 +01:00
committed by GitHub
5 changed files with 109 additions and 1 deletions

View File

@@ -3,6 +3,7 @@
## 3.6.1.dev
* Fix: MOVE failing with URL-encoded destination header
* Improve: add workaround to remove empty lines in item to avoid reject by vobject parser
## 3.6.0

View File

@@ -4,7 +4,7 @@
# Copyright © 2014 Jean-Marc Martins
# Copyright © 2008-2017 Guillaume Ayoub
# Copyright © 2017-2022 Unrud <unrud@outlook.com>
# Copyright © 2024-2025 Peter Bieringer <pb@bieringer.de>
# Copyright © 2024-2026 Peter Bieringer <pb@bieringer.de>
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -56,6 +56,8 @@ def read_components(s: str) -> List[vobject.base.Component]:
# * 0x0A Line Feed
# * 0x0D Carriage Return
s = re.sub(r'[\x00-\x08\x0B\x0C\x0E-\x1F]', '', s)
# Workaround delete all empty lines to avoid vobject parsing errors
s = re.sub(r'(?m)^[ \t]*\r?\n', '', s)
return list(vobject.readComponents(s, allowQP=True))

View File

@@ -0,0 +1,38 @@
BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Europe/Paris
X-LIC-LOCATION:Europe/Paris
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CREATED:20130902T150157Z
LAST-MODIFIED:20130902T150158Z
DTSTAMP:20130902T150158Z
UID:event1
SUMMARY:Event
CATEGORIES:some_category1,another_category2
DESCRIPTION:Line1
Line2
Line3
ORGANIZER:mailto:unclesam@example.com
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;CN=Jane Doe:MAILTO:janedoe@example.com
ATTENDEE;ROLE=REQ-PARTICIPANT;DELEGATED-FROM="MAILTO:bob@host.com";PARTSTAT=ACCEPTED;CN=John Doe:MAILTO:johndoe@example.com
DTSTART;TZID=Europe/Paris:20130901T180000
DTEND;TZID=Europe/Paris:20130901T190000
END:VEVENT
END:VCALENDAR

View File

@@ -0,0 +1,39 @@
BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Europe/Paris
X-LIC-LOCATION:Europe/Paris
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CREATED:20130902T150157Z
LAST-MODIFIED:20130902T150158Z
DTSTAMP:20130902T150158Z
UID:event1
SUMMARY:Event having description with empty line
CATEGORIES:some_category1,another_category2
DESCRIPTION:Line1
Line2
Line4
ORGANIZER:mailto:unclesam@example.com
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;CN=Jane Doe:MAILTO:janedoe@example.com
ATTENDEE;ROLE=REQ-PARTICIPANT;DELEGATED-FROM="MAILTO:bob@host.com";PARTSTAT=ACCEPTED;CN=John Doe:MAILTO:johndoe@example.com
DTSTART;TZID=Europe/Paris:20130901T180000
DTEND;TZID=Europe/Paris:20130901T190000
END:VEVENT
END:VCALENDAR

View File

@@ -144,6 +144,34 @@ permissions: RrWw""")
assert "Event" in answer
assert "UID:event" in answer
def test_add_event_with_desc_ok(self) -> None:
"""Add an event."""
self.mkcalendar("/calendar.ics/")
event = get_file_content("event_issue1970_ok.ics")
path = "/calendar.ics/event_issue1970_ok.ics"
self.put(path, event)
_, headers, answer = self.request("GET", path, check=200)
assert "ETag" in headers
assert headers["Content-Type"] == "text/calendar; charset=utf-8"
assert "DESCRIPTION" in answer
assert "VEVENT" in answer
assert "Event" in answer
assert "UID:event" in answer
def test_add_event_with_desc_problem(self) -> None:
"""Add an event."""
self.mkcalendar("/calendar.ics/")
event = get_file_content("event_issue1970_problem.ics")
path = "/calendar.ics/event_issue1970_problem.ics"
self.put(path, event)
_, headers, answer = self.request("GET", path, check=200)
assert "ETag" in headers
assert headers["Content-Type"] == "text/calendar; charset=utf-8"
assert "DESCRIPTION" in answer
assert "VEVENT" in answer
assert "Event" in answer
assert "UID:event" in answer
def test_add_event_exceed_size(self) -> None:
"""Add an event which is exceeding max-resource-size."""
self.configure({"server": {"max_resource_size": 20}})