Describe the bug
When a property's value type is unknown (unrecognized properties, including
X- properties without a VALUE parameter), the value seems to be run through
RFC 5545 TEXT escaping rules instead of being kept as written. As I read
RFC 7265 §5.1/§5.2, an unknown value should be passed through "without
processing."
The problem does not look limited to jCal. In my testing, the value changes in
three places:
- Just reading it — the value I get back from
from_ical is already
different from the source, before I write anything out.
- iCal → iCal round-trip — iCalendar in, iCalendar out, no jCal involved;
backslashes are added or removed.
- iCal → jCal — the case RFC 7265 §5.1 warns "breaks round-tripping
values."
I think the jCal case (3) is a clear RFC 7265 violation. I am less sure about
the plain-iCal cases (1, 2).
To reproduce
from icalendar.cal import Component
orig = r"""BEGIN:VEVENT
UID:1
X-MYSTERY:a;b\,c\:d\ne
END:VEVENT
"""
ev = Component.from_ical(orig)
print(repr(str(ev["X-MYSTERY"]))) # just reading it
print(ev.to_ical().decode()) # iCal -> iCal
print(ev.to_jcal()) # iCal -> jCal
Output:
'a;b,c:d\ne' # read: \, -> , \: -> : \n -> real newline
BEGIN:VEVENT
UID:1
X-MYSTERY:a\;b\,c:d\ne # iCal: ; -> \; \, kept \: -> :
END:VEVENT
['vevent', [['uid', {}, 'text', '1'], ['x-mystery', {}, 'unknown', 'a;b,c:d\ne']], []]
# jCal: \, -> , (kept in iCal above, lost here -> breaks round-tripping, RFC 7265 §5.3)
The source value a;b\,c\:d\ne is preserved by none of the three. The escaped
\, is the clearest case — it survives the iCal → iCal round-trip but loses its
backslash in jCal. Across my tests the affected characters were ,, ;, \,
:, and newlines; others came through unchanged, though I have not tried every
input.
Expected behavior
As I read RFC 7265 §5.1/§5.2 and the §5.3 example, an unknown value should
come through exactly as written, in both directions. For the input above that
would mean:
>>> str(ev["X-MYSTERY"])
'a;b\\,c\\:d\\ne'
>>> print(ev.to_ical().decode())
...
X-MYSTERY:a;b\,c\:d\ne
...
>>> ev.to_jcal()
['vevent', [['uid', {}, 'text', '1'], ['x-mystery', {}, 'unknown', 'a;b\\,c\\:d\\ne']], []]
i.e. no RFC 5545 escaping or unescaping for unknown values either way (only
JSON string escaping, which the JSON layer does on its own).
The RFC 7265 §5.3 example shows the same idea — the decoded jCal value matches
the iCalendar value exactly:
|
value |
| iCalendar |
Stenophylla;Guinea\,Africa |
| jCal (decoded) |
Stenophylla;Guinea\,Africa |
Environment
Additional context
One case I have not worked out: a jCal unknown string could hold a character
(such as a raw line break) that RFC 5545 may not be able to put in a bare
value, so passing it through unchanged could clash with producing valid
iCalendar. The RFC examples do not seem to cover this.
Describe the bug
When a property's value type is
unknown(unrecognized properties, includingX-properties without aVALUEparameter), the value seems to be run throughRFC 5545 TEXT escaping rules instead of being kept as written. As I read
RFC 7265 §5.1/§5.2, an
unknownvalue should be passed through "withoutprocessing."
The problem does not look limited to jCal. In my testing, the value changes in
three places:
from_icalis alreadydifferent from the source, before I write anything out.
backslashes are added or removed.
values."
I think the jCal case (3) is a clear RFC 7265 violation. I am less sure about
the plain-iCal cases (1, 2).
To reproduce
Output:
'a;b,c:d\ne' # read: \, -> , \: -> : \n -> real newline BEGIN:VEVENT UID:1 X-MYSTERY:a\;b\,c:d\ne # iCal: ; -> \; \, kept \: -> : END:VEVENT ['vevent', [['uid', {}, 'text', '1'], ['x-mystery', {}, 'unknown', 'a;b,c:d\ne']], []] # jCal: \, -> , (kept in iCal above, lost here -> breaks round-tripping, RFC 7265 §5.3)The source value
a;b\,c\:d\neis preserved by none of the three. The escaped\,is the clearest case — it survives the iCal → iCal round-trip but loses itsbackslash in jCal. Across my tests the affected characters were
,,;,\,:, and newlines; others came through unchanged, though I have not tried everyinput.
Expected behavior
As I read RFC 7265 §5.1/§5.2 and the §5.3 example, an
unknownvalue shouldcome through exactly as written, in both directions. For the input above that
would mean:
i.e. no RFC 5545 escaping or unescaping for
unknownvalues either way (onlyJSON string escaping, which the JSON layer does on its own).
The RFC 7265 §5.3 example shows the same idea — the decoded jCal value matches
the iCalendar value exactly:
Stenophylla;Guinea\,AfricaStenophylla;Guinea\,AfricaEnvironment
icalendarversion: 7.1.2Additional context
One case I have not worked out: a jCal
unknownstring could hold a character(such as a raw line break) that RFC 5545 may not be able to put in a bare
value, so passing it through unchanged could clash with producing valid
iCalendar. The RFC examples do not seem to cover this.
main)..icssample file, or there is no.icssample file. (Reproducer is inline above.)