Skip to content

Commit

Permalink
Fixes for better handling of incoming vCard4 (Fixes: #411)
Browse files Browse the repository at this point in the history
  • Loading branch information
mstilkerich committed Dec 26, 2022
1 parent 34f7341 commit be84b24
Show file tree
Hide file tree
Showing 17 changed files with 143 additions and 6 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

- Fix: Internal server error with PHP8 when searching address fields of contacts (Fixes: #410)
- Fix: Assertion failure in DelayedPhotoLoader (Fixes: #404)
- Fixes for better handling of incoming vCard4 (Fixes: #411)
- Handle data-URI-style inline PHOTO as used in vCard4
- Use VCard conversion to handle v4 properties such as KIND=group for which extensions are used in v3 vCards

## Version 5.0.0-beta1 (to 4.4.4)

Expand Down
43 changes: 42 additions & 1 deletion src/DataConversion.php
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,11 @@ public function isMultivalueProperty(string $attrname): bool
*/
public function toRoundcube(VCard $vcard, AddressbookCollection $davAbook): array
{
// in case our input is not a v3 vcard, first convert it to one
if ($vcard->getDocumentType() != VObject\Document::VCARD30) {
$vcard = $vcard->convert(VObject\Document::VCARD30);
}

$save_data = [
// DEFAULTS
'kind' => 'individual',
Expand Down Expand Up @@ -494,9 +499,16 @@ public function fromRoundcube(array $save_data, ?VCard $vcard = null): VCard
$save_data["name"] = $this->composeDisplayname($save_data);
}

if (!isset($vcard)) {
if (isset($vcard)) {
$vcardVersion = $vcard->getDocumentType();
if ($vcardVersion != VObject\Document::VCARD30) {
$vcard4 = $vcard;
$vcard = $vcard->convert(VObject\Document::VCARD30);
}
} else {
// create fresh minimal vcard
$vcard = new VObject\Component\VCard(['VERSION' => '3.0']);
$vcardVersion = VObject\Document::VCARD30;
}

// set product
Expand All @@ -522,6 +534,21 @@ public function fromRoundcube(array $save_data, ?VCard $vcard = null): VCard
$this->setSingleValueProperties($save_data, $vcard);
$this->setMultiValueProperties($save_data, $vcard);

// if the original vcard was version 4, convert it back to that version
if ($vcardVersion == VObject\Document::VCARD40) {
// XXX Temporary workarounds for sabre-io/vobject#602 BEGIN
// 1) If the photo was unchanged, preserve the original vcard's property to not lose the mimetype
$vcard = $vcard->convert(VObject\Document::VCARD40);
if (isset($vcard4->PHOTO) && !isset($save_data['photo'])) {
$vcard->PHOTO = $vcard4->PHOTO;
}

// 2) Drop X-ADDRESSBOOKSERVER-KIND property; for KIND=group, it has been converted, for KIND=individual it
// it has been retained, but since it is the default we can simply drop it.
unset($vcard->{'X-ADDRESSBOOKSERVER-KIND'});
// XXX Temporary workarounds for sabre-io/vobject#602 END
}

return $vcard;
}

Expand Down Expand Up @@ -608,6 +635,20 @@ private static function setPhotoProperty(VCard $vcard, string $photoData): void
if (isset($vcard->PHOTO)) {
$vcard->PHOTO['ENCODING'] = 'b';
$vcard->PHOTO['VALUE'] = 'binary';

if (function_exists('getimagesizefromstring')) {
$typemap = [
IMAGETYPE_JPEG => 'JPEG',
IMAGETYPE_GIF => 'GIF',
IMAGETYPE_PNG => 'PNG',
];
$imginfo = getimagesizefromstring($photoData);
if ($imginfo !== false && isset($imginfo[2]) && is_int($imginfo[2])) {
if (key_exists($imginfo[2], $typemap)) {
$vcard->PHOTO['TYPE'] = $typemap[$imginfo[2]];
}
}
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public static function comparePhoto(string $pExpStr, string $pRcStr): void
TestCase::assertTrue(function_exists('gd_info'), "php-gd required");

// shortcut that also covers URI - if identical strings, save the comparison
if (empty($pExpStr) || empty($pRcStr) || str_contains($pExpStr, "http")) {
if (empty($pExpStr) || empty($pRcStr) || str_contains($pExpStr, "http") || str_contains($pExpStr, "data:")) {
TestCase::assertSame($pExpStr, $pRcStr, "PHOTO comparison on URI value failed");
return;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/data/vcardCreate/InlinePhoto.vcf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ FN:Max Mustermann
EMAIL:[email protected]
PRODID:-//Apple Inc.//iCloud Web Address Book 2018B71//EN
REV:2020-10-03T10:30:20Z
PHOTO;ENCODING=b;VALUE=binary:
PHOTO;ENCODING=b;VALUE=binary;TYPE=JPEG:
/9j/4AAQSkZJRgABAQEASABIAAD/4RrgRXhpZgAATU0AKgAAAAgACQEPAAIAAAAGAAAAegEQAAI
AAAAKAAAAgAEaAAUAAAABAAAAigEbAAUAAAABAAAAkgEoAAMAAAABAAIAAAExAAIAAAALAAAAmg
EyAAIAAAAUAAAApgITAAMAAAABAAEAAIdpAAQAAAABAAAAugAAA/5BcHBsZQBpUGhvbmUgNnMAA
Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/data/vcardExport/PhotoInlined.vcf.exported
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ FN:Max Mustermann
EMAIL;TYPE=internet:[email protected]
PRODID:-//Apple Inc.//iCloud Web Address Book 2018B71//EN
REV:2020-10-03T10:30:20Z
PHOTO;ENCODING=b;VALUE=binary:
PHOTO;ENCODING=b;VALUE=binary;TYPE=PNG:
iVBORw0KGgoAAAANSUhEUgAAALUAAAC1CAIAAACWMSn+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAA
gAElEQVR4nGS8WW8sS5ImZpu7R0QuJJPkIc+5W+0109XV3dMttTB6EiAJ/TjST5UAQdACvUyjAU
HSTC/q9VbV3c/OLTNjc3cz00PwsA5G8UAkMzwiyTBzs+/7zCzxlxenjoaIrLYSOm+6XWhPsfmkO
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ FN:Max Mustermann
EMAIL;TYPE=internet:[email protected]
PRODID:-//Apple Inc.//iCloud Web Address Book 2018B71//EN
REV:2020-10-03T10:30:20Z
PHOTO;ENCODING=b;VALUE=binary:
PHOTO;ENCODING=b;VALUE=binary;TYPE=PNG:
iVBORw0KGgoAAAANSUhEUgAAALUAAAC1CAIAAACWMSn+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAA
gAElEQVR4nGS8WW8sS5ImZpu7R0QuJJPkIc+5W+0109XV3dMttTB6EiAJ/TjST5UAQdACvUyjAU
HSTC/q9VbV3c/OLTNjc3cz00PwsA5G8UAkMzwiyTBzs+/7zCzxlxenjoaIrLYSOm+6XWhPsfmkO
Expand Down
1 change: 1 addition & 0 deletions tests/Unit/data/vcardImport/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ There are a few specifics to be tested during the import:
- IM-KAddressbook: A VCard containing instant messaging attributes produced by KAddressbook
- IM-Nextcloud: A VCard containing instant messaging attributes produced by nextcloud
- IM-Owncloud: A VCard containing instant messaging attributes produced by owncloud
- VCard4-DataUriPhoto: A v4 VCard containing a PHOTO in data URI format.
- ZeroStrings: Tests "0" strings in various places of the VCard, which are considered "empty" by php's empty function.
This must not cause these properties to be discarded during the import like properties with no value.

9 changes: 9 additions & 0 deletions tests/Unit/data/vcardImport/VCard4-DataUriPhoto.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"cuid": "5cdac90f-cb4c-4c1c-ad66-fe8591bdf3a2",
"name": "vCard 4 Contact with image",
"kind": "individual",
"email:other": [
"[email protected]"
],
"photo": "@../srv/pixel.jpg"
}
12 changes: 12 additions & 0 deletions tests/Unit/data/vcardImport/VCard4-DataUriPhoto.vcf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
BEGIN:VCARD
VERSION:4.0
PRODID:-//Thunderbird.net/NONSGML Thunderbird CardBook V83.6//EN-GB
UID:5cdac90f-cb4c-4c1c-ad66-fe8591bdf3a2
FN:vCard 4 Contact with image
EMAIL:[email protected]
REV:20221222T213003Z
PHOTO:data:image/JPEG\;base64\,/9j/4AAQSkZJRgABAQAAYABgAAD/2wBDAAgGBgcGBQgHB
wcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/
wAALCAABAAEBAREA/8QAFAABAAAAAAAAAAAAAAAAAAAAAv/EABQQAQAAAAAAAAAAAAAAAAAAAAD
/2gAIAQEAAD8AL//Z
END:VCARD
2 changes: 1 addition & 1 deletion tests/Unit/data/vcardUpdate/PhotoUpdated.vcf.new
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ FN:Max Mustermann
EMAIL:[email protected]
PRODID:-//Apple Inc.//iCloud Web Address Book 2018B71//EN
REV:2020-10-03T10:30:20Z
PHOTO;ENCODING=b;VALUE=binary:
PHOTO;ENCODING=b;VALUE=binary;TYPE=PNG:
iVBORw0KGgoAAAANSUhEUgAAALUAAAC1CAIAAACWMSn+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAA
gAElEQVR4nGS8WW8sS5ImZpu7R0QuJJPkIc+5W+0109XV3dMttTB6EiAJ/TjST5UAQdACvUyjAU
HSTC/q9VbV3c/OLTNjc3cz00PwsA5G8UAkMzwiyTBzs+/7zCzxlxenjoaIrLYSOm+6XWhPsfmkO
Expand Down
2 changes: 2 additions & 0 deletions tests/Unit/data/vcardUpdate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@ preserved.
- XABLabel: Two EMAIL properties have a custom label given with X-ABLabel in the original VCard. One of the addresses
gets a new custom attribute, while the other one retains the original custom label.
- Group: Update a KIND=group VCard to have a new group name
- VCard4-DataUriPhotoUnchanged: Preserve inline photo including mime-type in v4 vcard
- VCard4-DataUriPhotoUpdated: Update an inline photo in a v4 vcard
- ZeroStrings: save data contains "0" values from some data fields, which are considered empty() by PHPs empty()
function. These properties must be properly set to 0 in the updated VCard, not omitted.
8 changes: 8 additions & 0 deletions tests/Unit/data/vcardUpdate/VCard4-DataUriPhotoUnchanged.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"cuid": "5cdac90f-cb4c-4c1c-ad66-fe8591bdf3a2",
"name": "vCard 4 Contact with image",
"kind": "individual",
"email:other": [
"[email protected]"
]
}
13 changes: 13 additions & 0 deletions tests/Unit/data/vcardUpdate/VCard4-DataUriPhotoUnchanged.vcf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
BEGIN:VCARD
VERSION:4.0
PRODID:-//Thunderbird.net/NONSGML Thunderbird CardBook V83.6//EN-GB
UID:5cdac90f-cb4c-4c1c-ad66-fe8591bdf3a2
FN:vCard 4 Contact with image
N:;;;;
EMAIL:[email protected]
REV:20221222T213003Z
PHOTO:data:image/JPEG\;base64\,/9j/4AAQSkZJRgABAQAAYABgAAD/2wBDAAgGBgcGBQgHB
wcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/
wAALCAABAAEBAREA/8QAFAABAAAAAAAAAAAAAAAAAAAAAv/EABQQAQAAAAAAAAAAAAAAAAAAAAD
/2gAIAQEAAD8AL//Z
END:VCARD
13 changes: 13 additions & 0 deletions tests/Unit/data/vcardUpdate/VCard4-DataUriPhotoUnchanged.vcf.new
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
BEGIN:VCARD
VERSION:4.0
PRODID:-//Thunderbird.net/NONSGML Thunderbird CardBook V83.6//EN-GB
UID:5cdac90f-cb4c-4c1c-ad66-fe8591bdf3a2
FN:vCard 4 Contact with image
N:;;;;
EMAIL:[email protected]
REV:20221222T213003Z
PHOTO:data:image/JPEG\;base64\,/9j/4AAQSkZJRgABAQAAYABgAAD/2wBDAAgGBgcGBQgHB
wcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/
wAALCAABAAEBAREA/8QAFAABAAAAAAAAAAAAAAAAAAAAAv/EABQQAQAAAAAAAAAAAAAAAAAAAAD
/2gAIAQEAAD8AL//Z
END:VCARD
9 changes: 9 additions & 0 deletions tests/Unit/data/vcardUpdate/VCard4-DataUriPhotoUpdated.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"cuid": "5cdac90f-cb4c-4c1c-ad66-fe8591bdf3a2",
"name": "vCard 4 Contact with image",
"kind": "individual",
"email:other": [
"[email protected]"
],
"photo": "@../srv/pixel.jpg"
}
13 changes: 13 additions & 0 deletions tests/Unit/data/vcardUpdate/VCard4-DataUriPhotoUpdated.vcf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
BEGIN:VCARD
VERSION:4.0
PRODID:-//Thunderbird.net/NONSGML Thunderbird CardBook V83.6//EN-GB
UID:5cdac90f-cb4c-4c1c-ad66-fe8591bdf3a2
FN:vCard 4 Contact with image
N:;;;;
EMAIL:[email protected]
REV:20221222T213003Z
PHOTO:data:image/JPEG\;base64\,/9j/4AAQSkZJRgABAQAAYABgAAD/2wBDAAgGBgcGBQgHB
wcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/
wAALCAABAAEBAREA/8QAFAABAAAAAAAAAAAAAAAAAAAAAv/EABQQAQAAAAAAAAAAAAAAAAAAAAD
/2gAIAQEAAD8AL//Z
END:VCARD
13 changes: 13 additions & 0 deletions tests/Unit/data/vcardUpdate/VCard4-DataUriPhotoUpdated.vcf.new
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
BEGIN:VCARD
VERSION:4.0
PRODID:-//Thunderbird.net/NONSGML Thunderbird CardBook V83.6//EN-GB
UID:5cdac90f-cb4c-4c1c-ad66-fe8591bdf3a2
FN:vCard 4 Contact with image
N:;;;;
EMAIL:[email protected]
REV:20221222T213003Z
PHOTO:data:image/jpeg;base64\,/9j/4AAQSkZJRgABAQAAYABgAAD/2wBDAAgGBgcGBQgHB
wcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/
wAALCAABAAEBAREA/8QAFAABAAAAAAAAAAAAAAAAAAAAAv/EABQQAQAAAAAAAAAAAAAAAAAAAAD
/2gAIAQEAAD8AL//Z
END:VCARD

0 comments on commit be84b24

Please sign in to comment.