diff options
author | Roeland Jago Douma <rullzer@users.noreply.github.com> | 2020-04-17 11:43:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-17 11:43:20 +0200 |
commit | ed56619a20ab6ab415c52cfdcb76576b15e56dff (patch) | |
tree | 00205ead07e34310e3c2b50b7fbc9d5ad17523f6 /apps/dav/lib | |
parent | 7c4b7e9329045a132d1fe2a3bdb943542d47662a (diff) | |
parent | fe4527a8e2275de51ea86715931e4df254b4fe23 (diff) | |
download | nextcloud-server-ed56619a20ab6ab415c52cfdcb76576b15e56dff.tar.gz nextcloud-server-ed56619a20ab6ab415c52cfdcb76576b15e56dff.zip |
Merge pull request #19901 from nextcloud/bugfix/noid/vcard-photo-handling
Improved vcard photo handling
Diffstat (limited to 'apps/dav/lib')
-rw-r--r-- | apps/dav/lib/CardDAV/CardDavBackend.php | 85 | ||||
-rw-r--r-- | apps/dav/lib/CardDAV/HasPhotoPlugin.php | 7 |
2 files changed, 77 insertions, 15 deletions
diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php index 71b7e846f3d..f4de1b717fb 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -449,7 +449,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { */ public function deleteAddressBook($addressBookId) { $query = $this->db->getQueryBuilder(); - $query->delete('cards') + $query->delete($this->dbCardsTable) ->where($query->expr()->eq('addressbookid', $query->createParameter('addressbookid'))) ->setParameter('addressbookid', $addressBookId) ->execute(); @@ -493,7 +493,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { public function getCards($addressBookId) { $query = $this->db->getQueryBuilder(); $query->select(['id', 'uri', 'lastmodified', 'etag', 'size', 'carddata', 'uid']) - ->from('cards') + ->from($this->dbCardsTable) ->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId))); $cards = []; @@ -501,7 +501,13 @@ class CardDavBackend implements BackendInterface, SyncSupport { $result = $query->execute(); while ($row = $result->fetch()) { $row['etag'] = '"' . $row['etag'] . '"'; - $row['carddata'] = $this->readBlob($row['carddata']); + + $modified = false; + $row['carddata'] = $this->readBlob($row['carddata'], $modified); + if ($modified) { + $row['size'] = strlen($row['carddata']); + } + $cards[] = $row; } $result->closeCursor(); @@ -524,7 +530,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { public function getCard($addressBookId, $cardUri) { $query = $this->db->getQueryBuilder(); $query->select(['id', 'uri', 'lastmodified', 'etag', 'size', 'carddata', 'uid']) - ->from('cards') + ->from($this->dbCardsTable) ->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId))) ->andWhere($query->expr()->eq('uri', $query->createNamedParameter($cardUri))) ->setMaxResults(1); @@ -535,7 +541,12 @@ class CardDavBackend implements BackendInterface, SyncSupport { return false; } $row['etag'] = '"' . $row['etag'] . '"'; - $row['carddata'] = $this->readBlob($row['carddata']); + + $modified = false; + $row['carddata'] = $this->readBlob($row['carddata'], $modified); + if ($modified) { + $row['size'] = strlen($row['carddata']); + } return $row; } @@ -562,7 +573,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { $query = $this->db->getQueryBuilder(); $query->select(['id', 'uri', 'lastmodified', 'etag', 'size', 'carddata', 'uid']) - ->from('cards') + ->from($this->dbCardsTable) ->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId))) ->andWhere($query->expr()->in('uri', $query->createParameter('uri'))); @@ -572,7 +583,13 @@ class CardDavBackend implements BackendInterface, SyncSupport { while ($row = $result->fetch()) { $row['etag'] = '"' . $row['etag'] . '"'; - $row['carddata'] = $this->readBlob($row['carddata']); + + $modified = false; + $row['carddata'] = $this->readBlob($row['carddata'], $modified); + if ($modified) { + $row['size'] = strlen($row['carddata']); + } + $cards[] = $row; } $result->closeCursor(); @@ -611,7 +628,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { $q = $this->db->getQueryBuilder(); $q->select('uid') - ->from('cards') + ->from($this->dbCardsTable) ->where($q->expr()->eq('addressbookid', $q->createNamedParameter($addressBookId))) ->andWhere($q->expr()->eq('uid', $q->createNamedParameter($uid))) ->setMaxResults(1); @@ -676,7 +693,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { $uid = $this->getUID($cardData); $etag = md5($cardData); $query = $this->db->getQueryBuilder(); - $query->update('cards') + $query->update($this->dbCardsTable) ->set('carddata', $query->createNamedParameter($cardData, IQueryBuilder::PARAM_LOB)) ->set('lastmodified', $query->createNamedParameter(time())) ->set('size', $query->createNamedParameter(strlen($cardData))) @@ -712,7 +729,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { $cardId = null; } $query = $this->db->getQueryBuilder(); - $ret = $query->delete('cards') + $ret = $query->delete($this->dbCardsTable) ->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId))) ->andWhere($query->expr()->eq('uri', $query->createNamedParameter($cardUri))) ->execute(); @@ -872,12 +889,41 @@ class CardDavBackend implements BackendInterface, SyncSupport { ]); } - private function readBlob($cardData) { + /** + * @param resource|string $cardData + * @param bool $modified + * @return string + */ + private function readBlob($cardData, &$modified=false) { if (is_resource($cardData)) { - return stream_get_contents($cardData); + $cardData = stream_get_contents($cardData); + } + + $cardDataArray = explode("\r\n", $cardData); + + $cardDataFiltered = []; + $removingPhoto = false; + foreach ($cardDataArray as $line) { + if (strpos($line, 'PHOTO:data:') === 0 + && strpos($line, 'PHOTO:data:image/') !== 0) { + // Filter out PHOTO data of non-images + $removingPhoto = true; + $modified = true; + continue; + } + + if ($removingPhoto) { + if (strpos($line, ' ') === 0) { + continue; + } + // No leading space means this is a new property + $removingPhoto = false; + } + + $cardDataFiltered[] = $line; } - return $cardData; + return implode("\r\n", $cardDataFiltered); } /** @@ -929,7 +975,11 @@ class CardDavBackend implements BackendInterface, SyncSupport { $result->closeCursor(); return array_map(function ($array) { - $array['carddata'] = $this->readBlob($array['carddata']); + $modified = false; + $array['carddata'] = $this->readBlob($array['carddata'], $modified); + if ($modified) { + $array['size'] = strlen($array['carddata']); + } return $array; }, $cards); } @@ -994,6 +1044,13 @@ class CardDavBackend implements BackendInterface, SyncSupport { $queryResult->closeCursor(); if (is_array($contact)) { + $modified = false; + $contact['etag'] = '"' . $contact['etag'] . '"'; + $contact['carddata'] = $this->readBlob($contact['carddata'], $modified); + if ($modified) { + $contact['size'] = strlen($contact['carddata']); + } + $result = $contact; } diff --git a/apps/dav/lib/CardDAV/HasPhotoPlugin.php b/apps/dav/lib/CardDAV/HasPhotoPlugin.php index bb847e74a37..cf9d68e14a4 100644 --- a/apps/dav/lib/CardDAV/HasPhotoPlugin.php +++ b/apps/dav/lib/CardDAV/HasPhotoPlugin.php @@ -62,7 +62,12 @@ class HasPhotoPlugin extends ServerPlugin { if ($node instanceof Card) { $propFind->handle($ns . 'has-photo', function () use ($node) { $vcard = Reader::read($node->get()); - return ($vcard instanceof VCard && $vcard->PHOTO); + return $vcard instanceof VCard + && $vcard->PHOTO + // Either the PHOTO is a url (doesn't start with data:) or the mimetype has to start with image/ + && (strpos($vcard->PHOTO->getValue(), 'data:') !== 0 + || strpos($vcard->PHOTO->getValue(), 'data:image/') === 0) + ; }); } } |