Skip to content
This repository was archived by the owner on Jun 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ androidx-rest-rules = "1.6.1"
desugar = "2.1.2"
dokka = "1.9.20"
ezvcard = "0.12.1"
guava = "33.3.1-android"
kotlin = "2.0.21"
junit = "4.13.2"

Expand All @@ -15,10 +16,11 @@ androidx-test-runner = { module = "androidx.test:runner", version.ref = "android
androidx-test-rules = { module = "androidx.test:rules", version.ref = "androidx-rest-rules" }
desugar = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugar" }
ezvcard = { module = "com.googlecode.ez-vcard:ez-vcard", version.ref = "ezvcard" }
guava = { module = "com.google.guava:guava", version.ref = "guava" }
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
junit = { module = "junit:junit", version.ref = "junit" }

[plugins]
android-library = { id = "com.android.library", version.ref = "agp" }
dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
1 change: 1 addition & 0 deletions lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ dependencies {
coreLibraryDesugaring(libs.desugar)

implementation(libs.androidx.annotation)
implementation(libs.guava)

// ez-vcard to parse/generate vCards
api(libs.ezvcard) { // requires Java 8
Expand Down
45 changes: 44 additions & 1 deletion lib/src/main/kotlin/at/bitfire/vcard4android/Contact.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package at.bitfire.vcard4android

import at.bitfire.vcard4android.property.CustomScribes.registerCustomScribes
import at.bitfire.vcard4android.property.XAbDate
import com.google.common.base.Ascii
import com.google.common.base.MoreObjects
import ezvcard.VCardVersion
import ezvcard.io.json.JCardReader
import ezvcard.io.text.VCardReader
Expand Down Expand Up @@ -80,6 +82,8 @@ data class Contact(
const val DATE_PARAMETER_OMIT_YEAR = "X-APPLE-OMIT-YEAR"
const val DATE_PARAMETER_OMIT_YEAR_DEFAULT = 1604

const val TO_STRING_MAX_VALUE_SIZE = 2000

/**
* Parses an InputStream that contains a vCard.
*
Expand Down Expand Up @@ -148,9 +152,48 @@ data class Contact(

override fun hashCode() = compareFields().contentHashCode()

/**
* Implements [Object.toString]. Truncates properties with potential big values:
*
* - [photo]
* - [unknownProperties]
*/
override fun toString() = MoreObjects.toStringHelper(this)
.omitNullValues()
.add("uid", uid)
.add("group", group)
.add("members", members)
.add("displayName", displayName)
.add("prefix", prefix)
.add("givenName", givenName)
.add("middleName", middleName)
.add("familyName", familyName)
.add("suffix", suffix)
.add("phoneticGivenName", phoneticGivenName)
.add("phoneticMiddleName", phoneticMiddleName)
.add("phoneticFamilyName", phoneticFamilyName)
.add("nickName", nickName)
.add("organization", organization)
.add("jobTitle", jobTitle)
.add("jobDescription", jobDescription)
.add("phoneNumbers", phoneNumbers)
.add("emails", emails)
.add("impps", impps)
.add("addresses", addresses)
.add("categories", categories)
.add("urls", urls)
.add("relations", relations)
.add("note", note?.let { Ascii.truncate(it, TO_STRING_MAX_VALUE_SIZE, "...") })
.add("anniversary", anniversary)
.add("birthDay", birthDay)
.add("customDates", customDates)
.add("photo", photo?.let { "byte[${it.size}]" })
.add("unknownProperties", unknownProperties?.let { Ascii.truncate(it, TO_STRING_MAX_VALUE_SIZE, "...") })
.toString()


interface Downloader {
fun download(url: String, accepts: String): ByteArray?
}

}
}
17 changes: 17 additions & 0 deletions lib/src/test/kotlin/at/bitfire/vcard4android/ContactTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ezvcard.parameter.ImppType
import ezvcard.parameter.RelatedType
import ezvcard.parameter.TelephoneType
import ezvcard.property.Birthday
import ezvcard.property.Email
import ezvcard.util.PartialDate
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
Expand All @@ -26,6 +27,7 @@ import java.nio.charset.Charset
import java.time.LocalDate
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.util.LinkedList

class ContactTest {

Expand All @@ -41,6 +43,21 @@ class ContactTest {
}


@Test
fun testToString_TruncatesLargeFields() {
val c = Contact(
displayName = "Test",
members = mutableSetOf("1", "2", "3"),
emails = LinkedList(listOf(LabeledProperty(Email("[email protected]")))),
note = "Some Text\n".repeat(1000),
photo = ByteArray(10*1024*1024) { 'A'.code.toByte() }, // 10 MB
unknownProperties = "UNKNOWN:Property\n".repeat(1000)
)
val result = c.toString()
assertTrue(result.length < 4500) // 2000 note + 2000 unknown properties + rest
}


@Test
fun testVCard3FieldsAsVCard3() {
val c = regenerate(parseContact("allfields-vcard3.vcf"), VCardVersion.V3_0)
Expand Down