Remove quotes from safe characters

pull/850/head
Nicco Kunzmann 2025-05-19 18:59:43 +01:00
rodzic 5fc38a8f86
commit e1b3386fb0
3 zmienionych plików z 108 dodań i 1 usunięć

Wyświetl plik

@ -129,7 +129,7 @@ def validate_param_value(value, quoted=True):
# chars presence of which in parameter value will be cause the value
# to be enclosed in double-quotes
QUOTABLE = re.compile("[,;: ']")
QUOTABLE = re.compile("[,;:]")
def dquote(val, always_quote=False):

Wyświetl plik

@ -0,0 +1,27 @@
BEGIN:VCALENDAR
METHOD:PUBLISH
PRODID:Microsoft Exchange Server 2010
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Eastern Standard Time
BEGIN:STANDARD
DTSTART:16010101T020000
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=11
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=2SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:minimal-demo-event-est-20241028@example.com
SUMMARY:Anonymous Test Event for TZID
DTSTART;TZID=Eastern Standard Time:20241028T170000
DTEND;TZID=Eastern Standard Time:20241028T180000
DTSTAMP:20250514T023916Z
END:VEVENT
END:VCALENDAR

Wyświetl plik

@ -0,0 +1,80 @@
"""Quoting the TZID parameter creates compatibility problems.
See https://github.com/collective/icalendar/issues/836
:rfc:`5545`:
.. code-block:: text
param-value = paramtext / quoted-string
paramtext = *SAFE-CHAR
quoted-string = DQUOTE *QSAFE-CHAR DQUOTE
SAFE-CHAR = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E
/ NON-US-ASCII
; Any character except CONTROL, DQUOTE, ";", ":", ","
NON-US-ASCII = UTF8-2 / UTF8-3 / UTF8-4
; UTF8-2, UTF8-3, and UTF8-4 are defined in [RFC3629]
"""
from datetime import datetime, time
from icalendar import Event, Parameters, vDDDTypes, vDatetime, vPeriod, vTime
import pytest
from icalendar.prop import vDDDLists
# All the controls except HTAB
CONTROL = {
i for i in range(256) if 0x00 <= i <= 0x08 or 0x0A <= i <= 0x1F or i == 0x7F
}
# Any character except CONTROL, DQUOTE, ";", ":", ","
SAFE_CHAR = set(range(256)) - CONTROL - set(b'";:,')
param_tzid = pytest.mark.parametrize(
"tzid",
[
"Europe/London",
"Eastern Standard Time",
]
)
@param_tzid
@pytest.mark.parametrize(
"vdt",
[
vDatetime(datetime(2024, 10, 11, 12, 0)),
vTime(time(23, 59, 59)),
vDDDTypes(datetime(2024, 10, 11, 12, 0)),
vPeriod((datetime(2024, 10, 11, 12, 0), datetime(2024, 10, 11, 13, 0))),
vDDDLists([datetime(2024, 10, 11, 12, 0)]),
]
)
def test_parameter_is_not_quoted_when_not_needed(tzid, vdt):
"""Check that serializing the value works without quoting."""
e = Event()
vdt.params["TZID"] = tzid
e["DTSTART"] = vdt
ics = e.to_ical().decode()
print(ics)
assert tzid in ics
assert f'"{tzid}' not in ics
assert f'{tzid}"' not in ics
@pytest.mark.parametrize(
"safe_char",
list(map(chr, sorted(SAFE_CHAR)))
)
def test_safe_char_is_not_escaped(safe_char):
"""Check that paramerter serialization is without quotes for safe chars."""
params = Parameters(tzid=safe_char)
result = params.to_ical().decode()
assert '"' not in result
def test_get_calendar_and_serialize_it_wihtout_quotes(calendars):
"""The example calendar should not contain the timezone with quotes."""
ics = calendars.issue_836_do_not_quote_tzid.to_ical().decode()
assert '"Eastern Standard' not in ics
assert 'Standard Time"' not in ics
assert "Eastern Standard Time" in ics