diff --git a/CHANGES.rst b/CHANGES.rst index 1fd9f88..cc0e355 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -15,8 +15,8 @@ New features: Bug fixes: -- *add item here* - +- Don't split content lines on the unicode ``LINE SEPARATOR`` character + ``\u2028`` but only on ``CRLF`` or ``LF``. 3.11.2 (2017-01-12) ------------------- diff --git a/setup.cfg b/setup.cfg index 2676bcf..0e4a9d4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,3 +10,6 @@ create-wheel = yes [wheel] universal = 1 + +[tool:pytest] +norecursedirs = .* env* docs *.egg src/icalendar/tests/hypothesis \ No newline at end of file diff --git a/src/icalendar/parser.py b/src/icalendar/parser.py index a5aa14f..4a5fc13 100644 --- a/src/icalendar/parser.py +++ b/src/icalendar/parser.py @@ -380,7 +380,7 @@ class Contentlines(list): # a fold is carriage return followed by either a space or a tab unfolded = uFOLD.sub('', st) lines = cls(Contentline(line) for - line in unfolded.splitlines() if line) + line in NEWLINE.split(unfolded) if line) lines.append('') # '\r\n' at the end of every content line return lines except: diff --git a/src/icalendar/tests/hypothesis/test_fuzzing.py b/src/icalendar/tests/hypothesis/test_fuzzing.py new file mode 100644 index 0000000..e32b279 --- /dev/null +++ b/src/icalendar/tests/hypothesis/test_fuzzing.py @@ -0,0 +1,35 @@ +import string + +from hypothesis import given, settings +import hypothesis.strategies as st + +from icalendar.parser import Contentline, Contentlines, Parameters +from icalendar.tests import unittest + + +def printable_characters(**kw): + return st.text( + st.characters(blacklist_categories=( + 'Cc', 'Cs' + ), **kw) + ) + +key = st.text(string.ascii_letters + string.digits, min_size=1) +value = printable_characters(blacklist_characters=u'\\;:\"') + + +class TestFuzzing(unittest.TestCase): + + @given(lines=st.lists( + st.tuples(key, st.dictionaries(key, value), value), + min_size=1 + )) + @settings(max_examples=10**9) + def test_main(self, lines): + cl = Contentlines() + for key, params, value in lines: + params = Parameters(**params) + cl.append(Contentline.from_parts(key, params, value)) + cl.append('') + + assert Contentlines.from_ical(cl.to_ical()) == cl diff --git a/tox.ini b/tox.ini index fc8b155..6743126 100644 --- a/tox.ini +++ b/tox.ini @@ -6,8 +6,10 @@ envlist = py26,py27,py33,py34,py35,py36 deps = pytest coverage + py{27,33,34,35,36}: hypothesis>=3.0 icalendar [test] commands = - coverage run --source=src/icalendar --omit=*/tests/* --module pytest [] src/icalendar + coverage run --source=src/icalendar --omit=*/tests/* --module pytest [] + py{27,33,34,35,36}: coverage run --append --source=src/icalendar --omit=*/tests/* --module pytest [] src/icalendar/tests/hypothesis/ coverage report coverage html