-
Notifications
You must be signed in to change notification settings - Fork 198
Description
Describe the bug
When importing a .vcf file with the (expected) escaped \; inside the PHOTO child value, the contact photo is not correctly displayed in the contact list.
Steps to reproduce
Create a contacts.vcf file like:
BEGIN:VCARD
VERSION:4.0
UID:898c5f96-8bfc-4d35-a198-085d25fb27c5
FN:JPEG escape
ORG:ASDF
PHOTO;VALUE=URI:data:image/jpeg\;base64\,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCACWAJYDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDfJLck5oHWkqWOPdy3ArpYCLGWUnsKjByKtO6rCRg4qoMAUhi9KlAJgbFQk1PEwEXzHApAVs+9IfSnzMhb5MYHeosj8aLgLuYcAkfSm7mPVmP40oVm6DNSfZpD6CpAhPWno5QcU97WRF3ZBAqMe9MC5HdIFAbI/CpUkQrkE8+1Z9X7U/uQM0BYesihjyfyp4kXPWkjcFiM08Ebu3SkMaZE3j5hTiVyOVoYLuHAqK5A8k8AfSgB1wBtGNvWiqGfeiqsA6NdzAVc4X5SeKrQ8ODV/aF560NkkE5BhPzfpVIitG6I8jrWe2FXJPSkmMY2AMmozckrsRfxpkkuQztwijP1rN/tG4kVvLgYKejAdq5KuJSdkdVOhfVl+SZYuGdQe/tUDarbxqABuI6mufuZpmlwQQB2JqJ33DODn0rlbnLVs2tGPQ3hryM2PK4z61OuqQSHaN4PaucCqQCTip1bYCR2HFO0ktxXi+h0EmobI1WKQlu+7pUkN1DOcLIu/uK51ZFkAQNwB8xNRg+WwKvhs8YqoynF6sUoxa0Or7VJDKEODWVp9+J8RSH5xwD61fHFd0JqRySjymlCEkztYZqTZ83bpWbGSCCDir0cisCxcjArREkjRfMDnFQXLBU2hsmopJTIfvHaKiOKYBmilCMeQpopgT/cfGelXYXMi4zgiqI5+tKjlD8pINJq4izdKqoMdazrgny+Bk1cmn8yMAjkd6pXDcAY/GolpEqK1Ofnv2EjpOpx0x6VXfVpliMKHMXQdjU+rtNJ8oRUUdx1NYx44rzFFNu56EpWSSJkfzDyeT3NJLhMgHmq6Md2KnWJ5G4BrRIxbuQhyV/GrO4lMZwatQ6W7YzwKvRadEB83JqkgMJlZVwOlNErKcYrfnsU2/IMVjXEO1iKdgLFi++eNSwX5hk12G0FdxjJ9wa4WElJAQehrudOmEtkjk5yK0paSsZVNiJcZ4p/50+RULFlamZrqMRfrVhY4goOf0pI4QcFsEVOxCqACKYMRnjCgBv0opzPx2opiGQodu7FE8IRN4PJqcxlEAFOMSspBBJ+tTcDO+tQyoxQgcg1ZmjMT7TUTdDQ1dDTsZN9bGaM7fTk1jLYM2ScAVr3ryboYcbVZuT60yQ4JHTFefy2bO5u6RQGnIBnvVy3hSJeRk0gY+tOBqkTYlDEn2qdFzzVZTk1YQkCtEOwrrkVk38QBzitbNV7qHzU4HIoaJOeCYf0rqfDsrfZZEz93pXPMMEg8EVsaKSsMp9cCojoyJr3TV8xicFjSg1Cp5xUhVlHIOK7DnJUldSAuDVsncg3KAfpWbuwe9TLcLwrs31FMTLpVcDKiio1eJl+WZvxopiLTBtmfManBGx/rDzSHJXlf1p4JwPl/WpApXIIkwW3VAamujmY5GKhNUUZd8rC7ikI/dp/OoLtcTtjoea1LmLfE30rM1RGEMAQ4Yr8xrknCzOmErogBUHqKdkEcc1luI0OGmdm9FqxbFlkAOdp9azNCyLkR54JNAvZZDhIwB7mrnkRPFkDBIrNlsg7FSSDmqSYF1JJj/c/Op0LEfMAPpVaG0hQDqSO9WwMCqQmYt8uJzgcVo6UfIgCzDCyHg+hpZIFknDYzjtQJUlV4XBDZ4zStZ3Dl5tDYtrcZO4nj0qfyAXILNiorbzBAnAzjvUyl9xyBnFdKOSWjKk9uYzkciocCtLDkjKg1Vu48fPtxmqJIABRSCigDZZl2nr+VPWRcDr+VMLDaeR+dKrDA6fnQIpzuGmYimUTMPOb603NMY8YJweh61m6tbp5aBWyucZFXweapXK5ilQdvmFZT2Nqe5jCCNTwOlP2gHPelJyKjeVUOWJrmOmxpQ/cGaSRQW4qFLj91mOPealBLIDtwfSqQrCouKfmkQ5p3FMGNBAbJpVh8+4U478Y9KZJjpuAPoa1NOWJYRISNx7k01qxSlyosJu6BG496UA7vuMPxoVk5w3604yJn79bo42BJGOGqG4HmIF+Yc+lSl1LD56bK4CgiQHmmIrC2ftk/hRV5WBUfOPzopgDKmzIjFKioV5jFU47hlXaTxViKQOCFfBHrQIqOw8xsDvSZprE7j9eaM0FD85FRyDkOO3B9xThn86uQ2ykZY5PpUtXKTsc1cx+VMyDp1FVyinqAa2tbtNgWVBwODWHIrn7jYFcslaR1wfMizCfLxt71aLqBywrJCOSN0jfhV63jRR0z7mhMpxHpPGWIzU24GomRXOcdKUcUySHzxHcSNtDNwAD0qYatIgx9njx9KpXA23LUmScUzmm9Tf068NzIylFAAzwKv8Ay56CsvRkBEjZ5wBWkF75NbRehm9RxALDKikcJx8o/KkYHIyxpkpZYyQ54qxWJtiEfdFFURdykDkflRQMc8MigsFJX1qPpzmtJVLx7ScCqs1q6AlTlaAK3NLRzQaBj4zh1J6ZrQ2g4ZeDWYKuWs2fkbqKQDp8SoY5F4PU1zt5Zvay7SMoeVPtXR+aGcqVYY7kcVm6nKJUmCcmMA4rOotDSlJ3MUAA1ZiIxVJpUYZGVNNFwy9Oa57nU0aeQKF5OaoRzO7YJ4q/FgLVp3IKFyc3T+1NU4pZuZ5D1GaaMVRzS3LyX76datMibhkBgami8TQSD5k2n60lpAtzaXMLDIZeM+tcpIhjdkbgqcGq1sCaOv8A+Ejtc8g5+tDa/aOpHPPvXGHNJzSux3R141ay9WorkNx9TRRdhdHqaZ2j5TxSSv8AumG09KaJuT92myz5ibkdK3Mij2oNJmkJpFCjJOAM03dg8ZBFPhmETkkZ44qMngs5CjrmpbGlcsPe7bZmc4I71h2d19qurwZyGj4qrrOp7l8iI/L3Iqno1x5OooT91vlNZTlc1Volh1zTdoq1fW5glyOY26Gq4GazcToTugQ7TxV+GTKiqIHPSrcRGMCnECNk2yTZgYhjwQajjNl8ofzM+xq8jD5g2SpHNJ5VqI8CHKj35rRanNUVmXtPWNC/kq6oQPvHvXN69B5GpSEDh/mFdXari3T6Vk+J4A1vHMBypxWyXumJy+aKKKzAbRSmikB6eG+f/wCtTbnHktkUUVsBnE0xj60UUiugkjCGIyONwHQCub1LVpZ2KDKr6UUVhJmsfhMpmLHJNKjlHVh1BzRRUEM7a2K3dookXIcfrWVcw/Zrho85HUGiitEtC6bdxI8OcEVNs2jiiipRuyS1+aYA1ck2iJ/kXgGiitInNV3LkQxCn+7WZ4i/5Bp/3hRRWvQxRyRpKKKxGIaKKKBH/9k=
END:VCARD
BEGIN:VCARD
VERSION:4.0
UID:c99a0a23-0800-417d-ba56-f3411628598c
FN:JPEG no escape
ORG:ASDF
PHOTO;VALUE=URI:data:image/jpeg;base64\,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
END:VCARD
Where the only difference is (note the escaped \; in one of them):
PHOTO;VALUE=URI:data:image/jpeg\;base64\,/9j/4AAQSkZJR...
PHOTO;VALUE=URI:data:image/jpeg;base64\,/9j/4AAQSkZJR...
Import the file into a new address book.
Right after importing, both contacts have a profile picture in the list and within the contact details:
Screencast.from.2024-10-20.02-05-10.webm
Now, after refreshing the view (or, basically, any time you open the contacts app afterwards), the escaped contact is not displayed on the list, nor when clicking the first time to see the contact details:
Screencast.from.2024-10-20.02-06-57.webm
The browser's console shows a 404 error on contact list load:
EDDD3AFC-D6B0-4D59-862E-D91CCA43E090.vcf:1
GET https://domain.com/remote.php/dav/addressbooks/users/User/asdf/EDDD3AFC-D6B0-4D59-862E-D91CCA43E090.vcf?photo 404 (Not Found)
Also, when downloading the address book as a .vcf file after import+refresh, the downloaded address book has two contacts with the following PHOTO value:
PHOTO;VALUE=URI:data:image/jpeg;base64\,/9j/4AAQSkZJR...
PHOTO;VALUE=URI:data:image/jpeg\\;base64\,/9j/4AAQSkZJR...
So, the unescaped contact is exported unescaped again, but the escaped contact is exported with two \\ next to the ;.
It looks like both exports are incorrect, since according to vobject:
import vobject
card = vobject.vCard()
card.add('fn')
card.fn.value = "John Doe"
card.add('photo')
card.photo.params = {"VALUE": ["URI"]}
card.photo.value = "URI:data:image/jpeg;base64,/9j/4AAQSkZJR..."
print(card.serialize())The serialization should be like (escaping both ; and ,):
BEGIN:VCARD
VERSION:3.0
FN:John Doe
PHOTO;VALUE=URI:URI:data:image/jpeg\;base64\,/9j/4AAQSkZJR...
END:VCARD
Expected behavior
- The correctly escaped
.vcf(with\;in the photo URI) should be displayed correctly in the contact list. - The exported
.vcfshould escape the\;too.
Actual behavior
- The correctly escaped
.vcf(with\;in the photo URI) is not displayed correctly in the contact list. - The exported
.vcfdoes not escape\;, or it escapes it twice (if it was imported with the escaped\;.
Contact version
6.1.0
Operating system
No response
PHP engine version
None
Web server
None
Database
None
Additional info
No response