mangstadt / ez-vcard

A vCard parser library for Java
Other
399 stars 92 forks source link

How to avoid escaping special character with backslash in vCard writer? #67

Closed stonio closed 7 years ago

stonio commented 7 years ago

Some popular e-mail clients can parse vCard 2.1 but keep backslash in property value. Backslash is necessary to escape special character like \, or \; :

Can you add an option to disable backslash escaping in vCard writer?

VCard vcard = new VCard();
vcard.addNote("foo,bar;baz");
String data = Ezvcard.write(vcard).version(VCardVersion.V2_1).go();
System.out.println(data);

Result

BEGIN:VCARD
VERSION:2.1
X-PRODID:ez-vcard 0.10.0
NOTE:foo\,bar\;baz
END:VCARD

Expected

BEGIN:VCARD
VERSION:2.1
X-PRODID:ez-vcard 0.10.0
NOTE:foo,bar;baz
END:VCARD
mangstadt commented 7 years ago

Thank you for reporting this. This brings up an important issue: The vCard version 2.1 specification does not require these characters to be escaped globally in all property values. The 3.0 and 4.0 specifications require these characters to be escaped everywhere, but the 2.1 specification does not. This has been fixed in 2380144cf35bc2c211874ac53db2d846fccffb97.

A workaround for the current version of ez-vcard is to add the NOTE property as an extended property:

VCard vcard = new VCard();
vcard.addExtendedProperty("NOTE", "foo,bar;baz");
Ezvcard.write(vcard).version(VCardVersion.V2_1).go(System.out);
stonio commented 7 years ago

Thanks for the fix in ez-vcard 0.10.1 .

Can you disable backslash escaping in vCard 2.1 address as well (and other properties such as name)?

// ez-vcard 0.10.1 
VCard vcard = new VCard();
Address address = new Address();
address.setStreetAddress("10, Downing Street");
vcard.addAddress(address);
Ezvcard.write(vcard).version(VCardVersion.V2_1).go(System.out);

Result

BEGIN:VCARD
VERSION:2.1
X-PRODID:ez-vcard 0.10.1
ADR:;;10\, Downing Street
END:VCARD

Expected

BEGIN:VCARD
VERSION:2.1
X-PRODID:ez-vcard 0.10.1
ADR:;;10, Downing Street
END:VCARD
mangstadt commented 7 years ago

Just reviewed the 2.1 spec. You're right, those comma characters should not be escaped.

Version 2.1 does not permit multiple components to exist inside of a structured value, like in versions 3.0 and 4.0. For example, you cannot define a N property that has multiple prefixes in version 2.1.

This will cause some inconsistency with internal the data model. I will have to review this.

As a workaround, you can define the address as an extended property instead:

VCard vcard = new VCard();
vcard.addExtendedProperty("ADR", ";;10, Downing Street");
Ezvcard.write(vcard).version(VCardVersion.V2_1).go(System.out);
mangstadt commented 7 years ago

Fixed in 313b012a771462d376f4d1763ed876943c9c0ce0.

Added validation warnings to the N and ADR properties, stating that multi-valued fields are not recognized in version 2.1.