Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Allow = in parameter values. #207

Merged
merged 5 commits into from
Apr 18, 2017
Merged

Conversation

geier
Copy link
Collaborator

@geier geier commented Dec 30, 2016

Some parameter values (e.g., BASE64 encoded binary data often ends with one or two equal signs) may contain an equal sign (=). The current implementation splits key-value pairs at all equal signs, which leads to errors. Especially icalendar files generated by Apple's software often feature BASE64 encoded binary data in parameter values.

This patch introduces a new parameter maxsplit to icalendar.parser.q_split() which works similar as python's string.split(sep, maxsplit) which we then use to split parameter key-value pairs only at the first equal sign.

This patch fixes #197.

@digsim
Copy link

digsim commented Dec 30, 2016

Regarding the test introduced in #204 one could argue to remove this test now. Its only purpose was to pinpoint a problem, which is getting fixed by this commit making this test obsolete. However, I would rather argue that the test should stay. I would therefore suggest to change line 20 into
self.assertEqual(len(event.errors), 0, 'Got too many errors'
and remove lines 21 and 22.

This second approach would then verify that:

  1. icalendar is able to parse a file containing binary information (already possible without this patch) and
  2. icalendar can do this without producing any errors (new with this patch).

@geier
Copy link
Collaborator Author

geier commented Dec 30, 2016

I have modified the old test and added a new one that tests the fix introduced in #204.

@geier
Copy link
Collaborator Author

geier commented Jan 2, 2017

Looks like I forgot to push those changes (done now). The failing test is pypy3, which we currently do not support, I have opened #206 to deal with that.

Copy link
Contributor

@untitaker untitaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q_split logic looks good to me

for event in cal.walk('vevent'):
self.assertEqual(len(event.errors), 0, 'Got too many errors')

except UnicodeEncodeError as e:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why catch the error at all?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly: no idea, I've just re-used the old test, but sure, we can remove it.

@geier geier force-pushed the fix_base64_equal branch 3 times, most recently from 605ec2c to 91a1648 Compare January 5, 2017 01:19
@geier
Copy link
Collaborator Author

geier commented Jan 5, 2017

I removed those try/excepts.

@untitaker
Copy link
Contributor

untitaker commented Jan 5, 2017 via email

@digsim
Copy link

digsim commented Jan 5, 2017

That should be ok. Back then, the except was used to let the test fail.

@geier
Copy link
Collaborator Author

geier commented Jan 18, 2017

I'd like to get someone else's review on this. @stlaz, @thet or @regebro, if you find the time, I'd really appreciate your input.

@stlaz
Copy link
Collaborator

stlaz commented Jan 18, 2017

Putting it on my TODO list

@regebro
Copy link
Contributor

regebro commented Jan 19, 2017

"=" is a SAFECHAR and should be allowed in unquoted values, so this is indeed a bug.
Only comment I have is that passing in maxsplit=0 doesn't return the expected result (no splits). It's a sufficiently silly case that you can choose not to support it.

untitaker added a commit to untitaker/icalendar that referenced this pull request Jan 19, 2017
This causes old PRs to add the changelog entry to already released
versions. It happened to me while rebasing collective#207
@untitaker
Copy link
Contributor

untitaker commented Jan 19, 2017 via email

@regebro
Copy link
Contributor

regebro commented Jan 19, 2017

Well, maxsplit=0 should reasonably not split at all. maxsplit=0 being the same as maxsplit=1 is even more confusing than it being the same as maxsplit=-1. :-)

@untitaker
Copy link
Contributor

untitaker commented Jan 19, 2017

maxsplit=0 returns a list with len = = 1, maxsplit=1 a list with len <= 2, just like str.split does. So 0 and 1 are indeed different cases here. Is there a particular testcase you tried that fails?

@untitaker
Copy link
Contributor

Ah, I see it fails in cases where there's nothing between the separator.

@untitaker
Copy link
Contributor

@regebro so that was a bug, fixed!

def test_q_split_bin(self):
from ..parser import q_split
for s in ('X-SOMETHING=ABCDE==', ',,,'):
for maxsplit in range(3):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest range(-1, 3) here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@geier
Copy link
Collaborator Author

geier commented Jan 19, 2017 via email

@stlaz
Copy link
Collaborator

stlaz commented Jan 19, 2017

@geier Thank you, I found that out right after I wrote that comment so I removed it :) Been in work for too long today.

Test if we support base64 encoded binary data in parameter values.
"""
directory = os.path.dirname(__file__)
data = open(os.path.join(directory, 'x_location.ics'), 'rb').read()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use a context manager here to fix the resource warning.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the way it's done throughout the test suite. I believe it's better to be consistent than to be right (in this case).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's no longer done this way, see #213

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, it isn't any more... alright, will fix

@untitaker
Copy link
Contributor

This conflicts with master, otherwise LGTM

@geier
Copy link
Collaborator Author

geier commented Jan 30, 2017

done

@geier
Copy link
Collaborator Author

geier commented Jan 30, 2017

I can force push into the branch, and your approval doesn't get auto-revoked!?

@geier geier force-pushed the fix_base64_equal branch 2 times, most recently from 3594e97 to c37b983 Compare February 15, 2017 13:31
@geier
Copy link
Collaborator Author

geier commented Feb 15, 2017

anybody got any idea why python 2.6 now fails on travis with

import unittest2 as unittest
E   ImportError: No module named unittest2

?

@geier
Copy link
Collaborator Author

geier commented Feb 15, 2017

As this group maintained, I'm not going to merge this myself, but I'd be grateful if somebody else would do it or voice their concerns.

I believe the current failure with python2.6 can safely be ignored, as it fails on master, too 😬

@WhyNotHugo
Copy link
Contributor

Any update on this? Looks ready, right?

Copy link
Contributor

@untitaker untitaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, though we should have multiple approvers

@untitaker
Copy link
Contributor

@regebro could you take a quick look at this again?

geier and others added 5 commits April 19, 2017 00:07
Some parameter values (e.g., BASE64 encoded binary data often ends with
one or two equal signs) may contain an equal sign (`=`). The current
implementation splits key-value pairs at all equal signs, which leads to
errors. Especially icalendar files generated by Apple's software often
feature BASE64 encoded binary data in parameter values.

This patch introduces a new parameter `maxsplit` to
icalendar.parser.q_split() which works similar as python's
string.split(sep, maxsplit) which we then use to split parameter
key-value pairs only at the first equal sign.

This patch fixes collective#197.
The fix for collective#197 makes the test data used for testing the error
messages for broken properties (which was valid data) work with
icalendar, we therefor need a new test with actually invalid data.
@geier geier merged commit 8a52e56 into collective:master Apr 18, 2017
@geier
Copy link
Collaborator Author

geier commented Apr 18, 2017

Thanks everyone who contributed!

@geier geier deleted the fix_base64_equal branch April 18, 2017 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

parameters with binary values including =
7 participants