Skip to content
This repository was archived by the owner on Jun 9, 2025. It is now read-only.

Commit 033c012

Browse files
committed
Contact.toString: truncate note, photo, unknown properties
1 parent 47404e9 commit 033c012

File tree

4 files changed

+65
-2
lines changed

4 files changed

+65
-2
lines changed

gradle/libs.versions.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ androidx-rest-rules = "1.6.1"
66
desugar = "2.1.2"
77
dokka = "1.9.20"
88
ezvcard = "0.12.1"
9+
guava = "33.3.1-android"
910
kotlin = "2.0.21"
1011
junit = "4.13.2"
1112

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

2123
[plugins]
2224
android-library = { id = "com.android.library", version.ref = "agp" }
2325
dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
24-
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
26+
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

lib/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ dependencies {
8686
coreLibraryDesugaring(libs.desugar)
8787

8888
implementation(libs.androidx.annotation)
89+
implementation(libs.guava)
8990

9091
// ez-vcard to parse/generate vCards
9192
api(libs.ezvcard) { // requires Java 8

lib/src/main/kotlin/at/bitfire/vcard4android/Contact.kt

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package at.bitfire.vcard4android
66

77
import at.bitfire.vcard4android.property.CustomScribes.registerCustomScribes
88
import at.bitfire.vcard4android.property.XAbDate
9+
import com.google.common.base.Ascii
10+
import com.google.common.base.MoreObjects
911
import ezvcard.VCardVersion
1012
import ezvcard.io.json.JCardReader
1113
import ezvcard.io.text.VCardReader
@@ -80,6 +82,8 @@ data class Contact(
8082
const val DATE_PARAMETER_OMIT_YEAR = "X-APPLE-OMIT-YEAR"
8183
const val DATE_PARAMETER_OMIT_YEAR_DEFAULT = 1604
8284

85+
const val TO_STRING_MAX_VALUE_SIZE = 2000
86+
8387
/**
8488
* Parses an InputStream that contains a vCard.
8589
*
@@ -148,9 +152,48 @@ data class Contact(
148152

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

155+
/**
156+
* Implements [Object.toString]. Truncates properties with potential big values:
157+
*
158+
* - [photo]
159+
* - [unknownProperties]
160+
*/
161+
override fun toString() = MoreObjects.toStringHelper(this)
162+
.omitNullValues()
163+
.add("uid", uid)
164+
.add("group", group)
165+
.add("members", members)
166+
.add("displayName", displayName)
167+
.add("prefix", prefix)
168+
.add("givenName", givenName)
169+
.add("middleName", middleName)
170+
.add("familyName", familyName)
171+
.add("suffix", suffix)
172+
.add("phoneticGivenName", phoneticGivenName)
173+
.add("phoneticMiddleName", phoneticMiddleName)
174+
.add("phoneticFamilyName", phoneticFamilyName)
175+
.add("nickName", nickName)
176+
.add("organization", organization)
177+
.add("jobTitle", jobTitle)
178+
.add("jobDescription", jobDescription)
179+
.add("phoneNumbers", phoneNumbers)
180+
.add("emails", emails)
181+
.add("impps", impps)
182+
.add("addresses", addresses)
183+
.add("categories", categories)
184+
.add("urls", urls)
185+
.add("relations", relations)
186+
.add("note", note?.let { Ascii.truncate(it, TO_STRING_MAX_VALUE_SIZE, "...") })
187+
.add("anniversary", anniversary)
188+
.add("birthDay", birthDay)
189+
.add("customDates", customDates)
190+
.add("photo", photo?.let { "byte[${it.size}]" })
191+
.add("unknownProperties", unknownProperties?.let { Ascii.truncate(it, TO_STRING_MAX_VALUE_SIZE, "...") })
192+
.toString()
193+
151194

152195
interface Downloader {
153196
fun download(url: String, accepts: String): ByteArray?
154197
}
155198

156-
}
199+
}

lib/src/test/kotlin/at/bitfire/vcard4android/ContactTest.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import ezvcard.parameter.ImppType
1111
import ezvcard.parameter.RelatedType
1212
import ezvcard.parameter.TelephoneType
1313
import ezvcard.property.Birthday
14+
import ezvcard.property.Email
1415
import ezvcard.util.PartialDate
1516
import org.junit.Assert.assertArrayEquals
1617
import org.junit.Assert.assertEquals
@@ -26,6 +27,7 @@ import java.nio.charset.Charset
2627
import java.time.LocalDate
2728
import java.time.OffsetDateTime
2829
import java.time.ZoneOffset
30+
import java.util.LinkedList
2931

3032
class ContactTest {
3133

@@ -41,6 +43,21 @@ class ContactTest {
4143
}
4244

4345

46+
@Test
47+
fun testToString_TruncatesLargeFields() {
48+
val c = Contact(
49+
displayName = "Test",
50+
members = mutableSetOf("1", "2", "3"),
51+
emails = LinkedList(listOf(LabeledProperty(Email("[email protected]")))),
52+
note = "Some Text\n".repeat(1000),
53+
photo = ByteArray(10*1024*1024) { 'A'.toByte() }, // 10 MB
54+
unknownProperties = "UNKNOWN:Property\n".repeat(1000)
55+
)
56+
val result = c.toString()
57+
assertTrue(result.length < 4500) // 2000 note + 2000 unknown properties + rest
58+
}
59+
60+
4461
@Test
4562
fun testVCard3FieldsAsVCard3() {
4663
val c = regenerate(parseContact("allfields-vcard3.vcf"), VCardVersion.V3_0)

0 commit comments

Comments
 (0)