Skip to content

Commit 6fd7714

Browse files
committed
properly encode exported names when appropriate
1 parent e4718ff commit 6fd7714

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

app/src/main/kotlin/com/simplemobiletools/contacts/helpers/QuotedPrintable.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.simplemobiletools.contacts.helpers
22

33
import java.io.ByteArrayOutputStream
4+
import java.net.URLEncoder
45

56
// https://alvinalexander.com/java/jwarehouse/android/core/java/com/google/android/mms/pdu/QuotedPrintable.java.shtml
67
object QuotedPrintable {
@@ -18,7 +19,7 @@ object QuotedPrintable {
1819
if (b == ESCAPE_CHAR.toInt()) {
1920
try {
2021
if ('\r' == bytes[i + 1].toChar() && '\n' == bytes[i + 2].toChar()) {
21-
i += 2
22+
i += 3
2223
continue
2324
}
2425

@@ -40,4 +41,24 @@ object QuotedPrintable {
4041
}
4142
return String(buffer.toByteArray())
4243
}
44+
45+
fun encode(value: String): String {
46+
val result = StringBuilder()
47+
value.forEach {
48+
if (it == ' ') {
49+
result.append(' ')
50+
} else {
51+
val urlEncoded = urlEncode(it.toString())
52+
if (urlEncoded == it.toString()) {
53+
val hex = String.format("%04x", it.toInt()).trimStart('0').toUpperCase()
54+
result.append("=$hex")
55+
} else {
56+
result.append(urlEncoded)
57+
}
58+
}
59+
}
60+
return result.toString()
61+
}
62+
63+
fun urlEncode(value: String) = URLEncoder.encode(value, "UTF-8").replace("+", " ").replace('%', '=')
4364
}

app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class VcfExporter {
3636
for (contact in contacts) {
3737
out.writeLn(BEGIN_VCARD)
3838
out.writeLn(VERSION_2_1)
39-
out.writeLn("$N:${contact.surname};${contact.firstName};${contact.middleName};;")
39+
out.writeLn("$N:${getNames(contact)}")
4040

4141
contact.phoneNumbers.forEach {
4242
out.writeLn("$TEL;${getPhoneNumberLabel(it.type)}:${it.value}")
@@ -91,6 +91,22 @@ class VcfExporter {
9191
})
9292
}
9393

94+
private fun getNames(contact: Contact): String {
95+
var firstName = contact.firstName
96+
var surName = contact.surname
97+
var middleName = contact.middleName
98+
99+
if (QuotedPrintable.urlEncode(firstName) != firstName
100+
|| QuotedPrintable.urlEncode(surName) != surName
101+
|| QuotedPrintable.urlEncode(middleName) != middleName) {
102+
firstName = QuotedPrintable.encode(firstName)
103+
surName = QuotedPrintable.encode(surName)
104+
middleName = QuotedPrintable.encode(middleName)
105+
}
106+
107+
return "$surName;$firstName;$middleName;;"
108+
}
109+
94110
private fun getPhoneNumberLabel(type: Int) = when (type) {
95111
CommonDataKinds.Phone.TYPE_MOBILE -> CELL
96112
CommonDataKinds.Phone.TYPE_HOME -> HOME

0 commit comments

Comments
 (0)