From 3fa9d96879a6bb5c8880a7f4d3dffef5c09217d4 Mon Sep 17 00:00:00 2001 From: Mario Mueller Date: Sat, 5 Nov 2016 07:16:05 +0100 Subject: [PATCH] Colon in `TYPE` meta field gets escaped and breaks lables on e.g. iPhone according to RFC, the comma/colon in the value of the `TYPE` must be supported. (Please see the example on https://tools.ietf.org/html/rfc6352#page-16). Escaping the colon leads to broken labels on e.g. the iPhone. --- src/vcard.js | 16 +++++++++++++++- test/vcard.generate.spec.js | 21 ++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/vcard.js b/src/vcard.js index e3f0efb..2d8121a 100644 --- a/src/vcard.js +++ b/src/vcard.js @@ -194,6 +194,15 @@ .replace(/,/g, '\\,') }; + var escapeTypeCharacters = function(v) { + if (typeof v === 'undefined') { + return ''; + } + return v + .replace(/\n/g, '\\n') + .replace(/;/g, '\\;') + }; + Object.keys(data).forEach(function (key) { if (!data[key] || typeof data[key].forEach !== 'function') { return; @@ -233,7 +242,12 @@ } value.meta[metaKey].forEach(function (metaValue) { if (metaKey.length > 0) { - line += ';' + escapeCharacters(metaKey.toUpperCase()) + '=' + escapeCharacters(metaValue); + if (metaKey.toUpperCase() === 'TYPE') { + // Do not escape the comma when it is the type property. This breaks a lot. + line += ';' + escapeCharacters(metaKey.toUpperCase()) + '=' + escapeTypeCharacters(metaValue); + } else { + line += ';' + escapeCharacters(metaKey.toUpperCase()) + '=' + escapeCharacters(metaValue); + } } }); }); diff --git a/test/vcard.generate.spec.js b/test/vcard.generate.spec.js index 773568d..682bf25 100644 --- a/test/vcard.generate.spec.js +++ b/test/vcard.generate.spec.js @@ -82,6 +82,21 @@ describe('vCard.generate', function () { ].join('\r\n')); }); + it('Should not break comma seperated type keys', function () { + var card = { + tel: [ + {value: '78884545247', meta: {type: ['HOME,PREF']}} + ] + }; + var string = vCard.generate(card); + + expect(string).toEqual([ + PREFIX, + 'TEL;TYPE=HOME,PREF:78884545247', + POSTFIX + ].join('\r\n')); + }); + it('Should generate vcard with multiple values of one metadata field', function () { var card = { tel: [ @@ -258,7 +273,7 @@ describe('vCard.generate', function () { ].join('\r\n')); }); - it('Should escape semicolon, colon and backslash in meta fields', function () { + it('Should escape semicolon and backslash in meta fields', function () { var card = { tel: [ {value: '78884545247', meta: {type: ['HO;,\\ME'], pref: ['1']}} @@ -268,7 +283,7 @@ describe('vCard.generate', function () { expect(string).toEqual([ PREFIX, - 'TEL;TYPE=HO\\;\\,\\ME;PREF=1:78884545247', + 'TEL;TYPE=HO\\;,\\ME;PREF=1:78884545247', POSTFIX ].join('\r\n')); }); @@ -298,7 +313,7 @@ describe('vCard.generate', function () { expect(string).toEqual([ PREFIX, - 'TEL;TYPE=HO\\;\\,\\ME;PREF=1:78884545247', + 'TEL;TYPE=HO\\;,\\ME;PREF=1:78884545247', POSTFIX ].join('\r\n')); });