From 648c8df51645147f99fd687511003062ae01978c Mon Sep 17 00:00:00 2001
From: Joas Schilling <coding@schilljs.com>
Date: Thu, 12 Mar 2020 11:26:31 +0100
Subject: [PATCH] Don't populate the PHOTO property when it's not an image

Signed-off-by: Joas Schilling <coding@schilljs.com>
---
 apps/dav/lib/CardDAV/CardDavBackend.php | 27 +++++++++++++++++++++++--
 apps/dav/lib/CardDAV/HasPhotoPlugin.php |  7 ++++++-
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php
index 1f87ca5f7c1..bfdf7e53f40 100644
--- a/apps/dav/lib/CardDAV/CardDavBackend.php
+++ b/apps/dav/lib/CardDAV/CardDavBackend.php
@@ -874,10 +874,33 @@ class CardDavBackend implements BackendInterface, SyncSupport {
 
 	private function readBlob($cardData) {
 		if (is_resource($cardData)) {
-			return stream_get_contents($cardData);
+			$cardData = stream_get_contents($cardData);
 		}
 
-		return $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;
+				continue;
+			}
+
+			if ($removingPhoto) {
+				if (strpos($line, ' ') === 0) {
+					continue;
+				}
+				// No leading space means this is a new property
+				$removingPhoto = false;
+			}
+
+			$cardDataFiltered[] = $line;
+		}
+
+		return implode("\r\n", $cardDataFiltered);
 	}
 
 	/**
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)
+				;
 			});
 		}
 	}
-- 
GitLab