Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit c410b073 authored by Ricki Hirner's avatar Ricki Hirner
Browse files

Contact photos: don't throw IllegalArgumentException on invalid photos

parent 76d56fed
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -110,12 +110,12 @@ class PhotoBuilderTest {
        }
    }

    @Test(expected = IllegalArgumentException::class)
    @Test
    fun testInsertPhoto_Invalid() {
        val contact = AndroidContact(addressBook, Contact().apply { displayName = "Contact with photo" }, null, null)
        contact.add()
        try {
            val photoUri = PhotoBuilder.insertPhoto(provider, testAccount, contact.id!!, ByteArray(100) /* invalid photo  */)
            assertNull(PhotoBuilder.insertPhoto(provider, testAccount, contact.id!!, ByteArray(100) /* invalid photo  */))
        } finally {
            contact.delete()
        }
+1 −6
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ import at.bitfire.vcard4android.contactrow.ContactProcessor
import at.bitfire.vcard4android.contactrow.PhotoBuilder
import org.apache.commons.lang3.builder.ToStringBuilder
import java.io.FileNotFoundException
import java.util.logging.Level

open class AndroidContact(
        open val addressBook: AndroidAddressBook<out AndroidContact, out AndroidGroup>
@@ -128,11 +127,7 @@ open class AndroidContact(
        id = ContentUris.parseId(resultUri)

        getContact().photo?.let { photo ->
            try {
            PhotoBuilder.insertPhoto(provider, addressBook.account, id!!, photo)
            } catch (e: IllegalArgumentException) {
                Constants.log.log(Level.WARNING, "Invalid contact photo", e)
            }
        }

        return resultUri
+7 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ import at.bitfire.vcard4android.Constants
import at.bitfire.vcard4android.Contact
import at.bitfire.vcard4android.ContactsStorageException
import at.bitfire.vcard4android.Utils.asSyncAdapter
import org.apache.commons.io.FileUtils
import java.util.logging.Level

class PhotoBuilder(dataRowUri: Uri, rawContactId: Long?, contact: Contact)
@@ -37,9 +38,8 @@ class PhotoBuilder(dataRowUri: Uri, rawContactId: Long?, contact: Contact)
         * @param rawContactId  ID of the raw contact ([RawContacts._ID]])
         * @param data          contact photo (binary data in a supported format like JPEG or PNG)
         *
         * @return URI of the raw contact display photo ([Photo.PHOTO_URI])
         * @return URI of the raw contact display photo ([Photo.PHOTO_URI]); null if image can't be decoded
         *
         * @throws IllegalArgumentException when the image can't be read by [BitmapFactory]
         * @throws ContactsStorageException when the image couldn't be written
         */
        fun insertPhoto(provider: ContentProviderClient, account: Account, rawContactId: Long, data: ByteArray): Uri? {
@@ -48,15 +48,17 @@ class PhotoBuilder(dataRowUri: Uri, rawContactId: Long?, contact: Contact)
            opts.inJustDecodeBounds = true
            BitmapFactory.decodeByteArray(data, 0, data.size, opts)
            val valid = opts.outHeight != -1 && opts.outWidth != -1
            if (!valid)
                throw IllegalArgumentException("BitmapFactory can't decode image")
            if (!valid) {
                Constants.log.log(Level.WARNING, "Ignoring invalid contact photo")
                return null
            }

            // write file to contacts provider
            val uri = RawContacts.CONTENT_URI.buildUpon()
                .appendPath(rawContactId.toString())
                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY)
                .build()
            Constants.log.log(Level.FINE, "Writing photo to $uri (${data.size} bytes)")
            Constants.log.log(Level.FINE, "Writing photo to $uri (${FileUtils.byteCountToDisplaySize(data.size.toLong())})")
            provider.openAssetFile(uri, "w")?.use { fd ->
                fd.createOutputStream()?.use { os ->
                    os.write(data)