From 6fd77147258c98b5a9f4fe4f66d9e8bdb983848f Mon Sep 17 00:00:00 2001 From: tibbi Date: Sat, 3 Feb 2018 23:17:19 +0100 Subject: [PATCH] properly encode exported names when appropriate --- .../contacts/helpers/QuotedPrintable.kt | 23 ++++++++++++++++++- .../contacts/helpers/VcfExporter.kt | 18 ++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/QuotedPrintable.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/QuotedPrintable.kt index 7d415cc9..ce974b81 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/QuotedPrintable.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/QuotedPrintable.kt @@ -1,6 +1,7 @@ package com.simplemobiletools.contacts.helpers import java.io.ByteArrayOutputStream +import java.net.URLEncoder // https://alvinalexander.com/java/jwarehouse/android/core/java/com/google/android/mms/pdu/QuotedPrintable.java.shtml object QuotedPrintable { @@ -18,7 +19,7 @@ object QuotedPrintable { if (b == ESCAPE_CHAR.toInt()) { try { if ('\r' == bytes[i + 1].toChar() && '\n' == bytes[i + 2].toChar()) { - i += 2 + i += 3 continue } @@ -40,4 +41,24 @@ object QuotedPrintable { } return String(buffer.toByteArray()) } + + fun encode(value: String): String { + val result = StringBuilder() + value.forEach { + if (it == ' ') { + result.append(' ') + } else { + val urlEncoded = urlEncode(it.toString()) + if (urlEncoded == it.toString()) { + val hex = String.format("%04x", it.toInt()).trimStart('0').toUpperCase() + result.append("=$hex") + } else { + result.append(urlEncoded) + } + } + } + return result.toString() + } + + fun urlEncode(value: String) = URLEncoder.encode(value, "UTF-8").replace("+", " ").replace('%', '=') } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt index 74cc6ad7..052447f0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt @@ -36,7 +36,7 @@ class VcfExporter { for (contact in contacts) { out.writeLn(BEGIN_VCARD) out.writeLn(VERSION_2_1) - out.writeLn("$N:${contact.surname};${contact.firstName};${contact.middleName};;") + out.writeLn("$N:${getNames(contact)}") contact.phoneNumbers.forEach { out.writeLn("$TEL;${getPhoneNumberLabel(it.type)}:${it.value}") @@ -91,6 +91,22 @@ class VcfExporter { }) } + private fun getNames(contact: Contact): String { + var firstName = contact.firstName + var surName = contact.surname + var middleName = contact.middleName + + if (QuotedPrintable.urlEncode(firstName) != firstName + || QuotedPrintable.urlEncode(surName) != surName + || QuotedPrintable.urlEncode(middleName) != middleName) { + firstName = QuotedPrintable.encode(firstName) + surName = QuotedPrintable.encode(surName) + middleName = QuotedPrintable.encode(middleName) + } + + return "$surName;$firstName;$middleName;;" + } + private fun getPhoneNumberLabel(type: Int) = when (type) { CommonDataKinds.Phone.TYPE_MOBILE -> CELL CommonDataKinds.Phone.TYPE_HOME -> HOME