diff options
author | Aleksander Machniak <alec@alec.pl> | 2022-11-02 13:53:31 +0300 |
---|---|---|
committer | Aleksander Machniak <alec@alec.pl> | 2022-11-02 13:53:31 +0300 |
commit | 249bc0e33854394faea7c59aaeeac30b415a3a9a (patch) | |
tree | 98ccff530999d6eadb2c64f4eb15d594c60597c3 | |
parent | 10f00d394640df5c2806270e472be8c95a4c8fdf (diff) |
Fix so N property always exists in a vCard export (#8771)
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_vcard.php | 27 | ||||
-rw-r--r-- | tests/Framework/VCard.php | 11 | ||||
-rw-r--r-- | tests/src/Csv2vcard/email.vcf | 4 | ||||
-rw-r--r-- | tests/src/Csv2vcard/outlook.vcf | 1 |
5 files changed, 33 insertions, 11 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c0ee80edd..65d5b84b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - Fix bug where some dialogs in an eml attachment preview would not close on mobile (#8627) - Fix bug where multiline data:image URI's in emails were stripped from the message on display (#8613) - Fix fatal error on identity page if Enigma plugin is misconfigured (#8719) +- Fix so N property always exists in a vCard export (#8771) ## Release 1.6.0 diff --git a/program/lib/Roundcube/rcube_vcard.php b/program/lib/Roundcube/rcube_vcard.php index f8499d667..dfa53f206 100644 --- a/program/lib/Roundcube/rcube_vcard.php +++ b/program/lib/Roundcube/rcube_vcard.php @@ -836,17 +836,22 @@ class rcube_vcard { $vcard = ''; - foreach ((array)$data as $type => $entries) { - // valid N has 5 properties - while ($type == "N" && is_array($entries[0]) && count($entries[0]) < 5) { - $entries[0][] = ""; - } + // Make sure FN is not empty (required by RFC2426) + if (empty($data['FN'])) { + $data['FN'] = !empty($data['EMAIL'][0][0]) ? $data['EMAIL'][0][0] : ''; + } - // make sure FN is not empty (required by RFC2426) - if ($type == "FN" && empty($entries) && !empty($data['EMAIL'][0][0])) { - $entries[0] = $data['EMAIL'][0][0]; - } + // Make sure N is not empty (required by RFC2426) + if (empty($data['N'])) { + $data['N'] = [['', '', '', '', '']]; + } + + // Valid N has 5 properties + while (isset($data['N'][0]) && is_array($data['N'][0]) && count($data['N'][0]) < 5) { + $data['N'][0][] = ''; + } + foreach ((array)$data as $type => $entries) { foreach ((array)$entries as $entry) { $attr = ''; if (is_array($entry)) { @@ -881,8 +886,8 @@ class rcube_vcard $value = $entry; } - // skip empty entries - if (self::is_empty($value)) { + // Skip empty entries that aren't required by vCard v3 format + if (!in_array($type, ['N', 'FN']) && self::is_empty($value)) { continue; } diff --git a/tests/Framework/VCard.php b/tests/Framework/VCard.php index 46d1e70e6..14f520bf0 100644 --- a/tests/Framework/VCard.php +++ b/tests/Framework/VCard.php @@ -191,4 +191,15 @@ class Framework_VCard extends PHPUnit\Framework\TestCase $this->assertEquals("1980-02-02", $vcard['birthday'][0]); } + + /** + * Test required fields in output (#8771) + */ + function test_required_fields() + { + $vcard = new rcube_vcard(); + $result = $vcard->export(); + + $this->assertSame($result, "BEGIN:VCARD\r\nVERSION:3.0\r\nFN:\r\nN:;;;;\r\nEND:VCARD"); + } } diff --git a/tests/src/Csv2vcard/email.vcf b/tests/src/Csv2vcard/email.vcf index 69912a639..80ba14d66 100644 --- a/tests/src/Csv2vcard/email.vcf +++ b/tests/src/Csv2vcard/email.vcf @@ -1,20 +1,24 @@ BEGIN:VCARD VERSION:3.0 FN:test1@domain.tld +N:;;;; EMAIL;TYPE=INTERNET;TYPE=PREF:test1@domain.tld END:VCARD BEGIN:VCARD VERSION:3.0 FN:test2@domain.tld +N:;;;; EMAIL;TYPE=INTERNET;TYPE=PREF:test2@domain.tld END:VCARD BEGIN:VCARD VERSION:3.0 FN:test3@domain.tld +N:;;;; EMAIL;TYPE=INTERNET;TYPE=PREF:test3@domain.tld END:VCARD BEGIN:VCARD VERSION:3.0 FN:test4@domain.tld +N:;;;; EMAIL;TYPE=INTERNET;TYPE=PREF:test4@domain.tld END:VCARD diff --git a/tests/src/Csv2vcard/outlook.vcf b/tests/src/Csv2vcard/outlook.vcf index ffd7e0550..7030ac9e1 100644 --- a/tests/src/Csv2vcard/outlook.vcf +++ b/tests/src/Csv2vcard/outlook.vcf @@ -1,6 +1,7 @@ BEGIN:VCARD VERSION:3.0 FN:test1@domain.tld +N:;;;; EMAIL;TYPE=INTERNET;TYPE=PREF:test1@domain.tld EMAIL;TYPE=INTERNET;TYPE=OTHER:test2@domain.tld EMAIL;TYPE=INTERNET;TYPE=OTHER:test3@domain.tld |