From 9115c5d42bff48b0896e3b3af3c09a55597e3f00 Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 15 Oct 2022 23:26:15 +0200 Subject: [PATCH] vCard phone-number escaping --- lib/ical/design.js | 13 +++++++++++++ test/parse_test.js | 3 ++- test/parser/escape_semicolon.json | 26 ++++++++++++++++++++++++++ test/parser/escape_semicolon.vcf | 23 +++++++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 test/parser/escape_semicolon.json create mode 100644 test/parser/escape_semicolon.vcf diff --git a/lib/ical/design.js b/lib/ical/design.js index 8ed2ba67..aad646f7 100644 --- a/lib/ical/design.js +++ b/lib/ical/design.js @@ -742,6 +742,19 @@ const vcardValues = extend(commonValues, { timestamp: icalValues['date-time'], "language-tag": { matches: /^[a-zA-Z0-9-]+$/ // Could go with a more strict regex here + }, + "phone-number": { + fromICAL: function(aValue) { + return Array.from(aValue).filter(function(c) { + return c === '\\' ? undefined : c; + }).join(''); + }, + + toICAL: function(aValue) { + return Array.from(aValue).map(function(c) { + return c === ',' || c === ";" ? '\\' + c : c; + }).join(''); + } } }); diff --git a/test/parse_test.js b/test/parse_test.js index 150e118d..41442ac4 100644 --- a/test/parse_test.js +++ b/test/parse_test.js @@ -39,7 +39,8 @@ suite('parserv2', function() { 'vcard.vcf', 'vcard_author.vcf', 'vcard3.vcf', - 'vcard_grouped.vcf' + 'vcard_grouped.vcf', + 'escape_semicolon.vcf' ]; list.forEach(function(path) { diff --git a/test/parser/escape_semicolon.json b/test/parser/escape_semicolon.json new file mode 100644 index 00000000..8429f68d --- /dev/null +++ b/test/parser/escape_semicolon.json @@ -0,0 +1,26 @@ +[ + "vcard", + [ + [ "version", {}, "text", "3.0" ], + [ "prodid", {}, "text", "-//Sabre//Sabre VObject 4.1.6//EN" ], + [ "uid", {}, "text", "ad612c16-fe12-4ec5-abf6-49998ee5ab88" ], + [ "fn", {}, "text", "First Last NextCloud" ], + [ "adr", { "type": "HOME" }, "text", [ "PO", "Street 2", "Street", "City", "AL", "zip", "Germany" ] ], + [ "adr", { "type": "WORK" }, "text", [ "PO W", "Street 2 W", "Street W", "City Work", "AL work", "zip Work", "Germany work" ] ], + [ "email", { "type": "HOME" }, "text", "home@gmx.de" ], + [ "email", { "type": "WORK" }, "text", "work@gmx.de" ], + [ "tel", { "type": [ "HOME", "VOICE" ] }, "phone-number", "11111111" ], + [ "tel", { "type": "CELL" }, "phone-number", "205333" ], + [ "tel", { "type": ["WORK", "FAX" ] }, "phone-number", "205246;;,;" ], + [ "tel", { "type": ["WORK", "VOICE" ] }, "phone-number", "222222" ], + [ "org", {}, "text", "Firma" ], + [ "bday", {}, "date-time", "2019-02-10T00:00:33" ], + [ "nickname", {}, "text", "Hugo" ], + [ "x-abdate", {"group": "item1"}, "date-and-or-time", "20190220T000035" ], + [ "x-ablabel", {"group": "item1"}, "unknown", "_$!!$_" ], + [ "x-anniversary", {}, "date-and-or-time", "20190220T000035" ], + [ "categories", {}, "text", "Test-Kontakte" ], + [ "rev", {}, "date-time", "2019-10-08T17:05:14Z" ] + ], + [] + ] \ No newline at end of file diff --git a/test/parser/escape_semicolon.vcf b/test/parser/escape_semicolon.vcf new file mode 100644 index 00000000..04d71890 --- /dev/null +++ b/test/parser/escape_semicolon.vcf @@ -0,0 +1,23 @@ +BEGIN:VCARD +VERSION:3.0 +PRODID:-//Sabre//Sabre VObject 4.1.6//EN +UID:ad612c16-fe12-4ec5-abf6-49998ee5ab88 +FN:First Last NextCloud +ADR;TYPE=HOME:PO;Street 2;Street;City;AL;zip;Germany +ADR;TYPE=WORK:PO W;Street 2 W;Street W;City Work;AL work;zip Work;Germany w + ork +EMAIL;TYPE=HOME:home@gmx.de +EMAIL;TYPE=WORK:work@gmx.de +TEL;TYPE="HOME,VOICE":11111111 +TEL;TYPE=CELL:205333 +TEL;TYPE="WORK,FAX":205246\;\;\,\; +TEL;TYPE="WORK,VOICE":222222 +ORG:Firma +BDAY:20190210T000033 +NICKNAME:Hugo +ITEM1.X-ABDATE;VALUE=DATE-AND-OR-TIME:20190220T000035 +ITEM1.X-ABLABEL:_$!!$_ +X-ANNIVERSARY;VALUE=DATE-AND-OR-TIME:20190220T000035 +CATEGORIES:Test-Kontakte +REV:20191008T170514Z +END:VCARD