summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChiao Cheng <chiaocheng@google.com>2012-10-17 18:29:02 -0700
committerChiao Cheng <chiaocheng@google.com>2012-10-19 13:54:27 -0700
commitd98c0fe9ab6a89129c31c510ccd629a2dca148af (patch)
treea1eb9b36fa1996654de425d7f09d3774519f709c
parent8d1f50f582dc384a164a42657c35187b0226bcc3 (diff)
downloadvcard-d98c0fe9ab6a89129c31c510ccd629a2dca148af.tar.gz
Allow importer to handle missing encoding attribute for FN.
- Removed separators from FN properties. - Adding fix on importer side since we cannot fix exporters that already exist. Bug: 7292017 Change-Id: I61c691c24828e63aac1920384e16461da7a03881
-rw-r--r--java/com/android/vcard/VCardBuilder.java11
-rw-r--r--java/com/android/vcard/VCardParserImpl_V21.java9
-rw-r--r--java/com/android/vcard/VCardUtils.java31
-rw-r--r--tests/src/com/android/vcard/tests/VCardBuilderTest.java4
-rw-r--r--tests/src/com/android/vcard/tests/VCardUtilsTests.java24
5 files changed, 66 insertions, 13 deletions
diff --git a/java/com/android/vcard/VCardBuilder.java b/java/com/android/vcard/VCardBuilder.java
index ce97f46..41d1f34 100644
--- a/java/com/android/vcard/VCardBuilder.java
+++ b/java/com/android/vcard/VCardBuilder.java
@@ -538,9 +538,15 @@ public class VCardBuilder {
// N
buildSinglePartNameField(VCardConstants.PROPERTY_N, displayName);
+ mBuilder.append(VCARD_ITEM_SEPARATOR);
+ mBuilder.append(VCARD_ITEM_SEPARATOR);
+ mBuilder.append(VCARD_ITEM_SEPARATOR);
+ mBuilder.append(VCARD_ITEM_SEPARATOR);
+ mBuilder.append(VCARD_END_OF_LINE);
// FN
buildSinglePartNameField(VCardConstants.PROPERTY_FN, displayName);
+ mBuilder.append(VCARD_END_OF_LINE);
} else if (VCardConfig.isVersion30(mVCardType)) {
appendLine(VCardConstants.PROPERTY_N, "");
@@ -576,11 +582,6 @@ public class VCardBuilder {
}
mBuilder.append(VCARD_DATA_SEPARATOR);
mBuilder.append(encodedPart);
- mBuilder.append(VCARD_ITEM_SEPARATOR);
- mBuilder.append(VCARD_ITEM_SEPARATOR);
- mBuilder.append(VCARD_ITEM_SEPARATOR);
- mBuilder.append(VCARD_ITEM_SEPARATOR);
- mBuilder.append(VCARD_END_OF_LINE);
}
/**
diff --git a/java/com/android/vcard/VCardParserImpl_V21.java b/java/com/android/vcard/VCardParserImpl_V21.java
index 9d802a5..401335f 100644
--- a/java/com/android/vcard/VCardParserImpl_V21.java
+++ b/java/com/android/vcard/VCardParserImpl_V21.java
@@ -589,7 +589,14 @@ import java.util.Set;
}
final String upperEncoding = mCurrentEncoding.toUpperCase();
- if (upperEncoding.equals(VCardConstants.PARAM_ENCODING_QP)) {
+ if (upperEncoding.equals(VCardConstants.PARAM_ENCODING_QP) ||
+ // If encoding attribute is missing, then attempt to detect QP encoding.
+ // This is to handle a bug where the android exporter was creating FN properties
+ // with missing encoding. b/7292017
+ (propertyNameUpper.equals(VCardConstants.PROPERTY_FN) &&
+ property.getParameters(VCardConstants.PARAM_ENCODING) == null &&
+ VCardUtils.appearsLikeAndroidVCardQuotedPrintable(propertyRawValue))
+ ) {
final String quotedPrintablePart = getQuotedPrintablePart(propertyRawValue);
final String propertyEncodedValue =
VCardUtils.parseQuotedPrintable(quotedPrintablePart,
diff --git a/java/com/android/vcard/VCardUtils.java b/java/com/android/vcard/VCardUtils.java
index a486d5d..5890fb4 100644
--- a/java/com/android/vcard/VCardUtils.java
+++ b/java/com/android/vcard/VCardUtils.java
@@ -15,18 +15,15 @@
*/
package com.android.vcard;
-import com.android.vcard.exception.VCardException;
-
-import android.content.ContentProviderOperation;
-import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.CommonDataKinds.Im;
import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.telephony.PhoneNumberUtils;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.Log;
+import com.android.vcard.exception.VCardException;
+
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
@@ -697,6 +694,30 @@ public class VCardUtils {
return true;
}
+ /**
+ * Checks to see if a string looks like it could be an android generated quoted printable.
+ *
+ * Identification of quoted printable is not 100% reliable since it's just ascii. But given
+ * the high number and exact location of generated = signs, there is a high likely-hood that
+ * it would be.
+ *
+ * @return True if it appears like android quoted printable. False otherwise.
+ */
+ public static boolean appearsLikeAndroidVCardQuotedPrintable(String value) {
+
+ // Quoted printable is always in multiple of 3s. With optional 1 '=' at end.
+ final int remainder = (value.length() % 3);
+ if (value.length() < 2 || (remainder != 1 && remainder != 0)) {
+ return false;
+ }
+ for (int i = 0; i < value.length(); i += 3) {
+ if (value.charAt(i) != '=') {
+ return false;
+ }
+ }
+ return true;
+ }
+
//// The methods bellow may be used by unit test.
/**
diff --git a/tests/src/com/android/vcard/tests/VCardBuilderTest.java b/tests/src/com/android/vcard/tests/VCardBuilderTest.java
index e86ca33..f7af0ff 100644
--- a/tests/src/com/android/vcard/tests/VCardBuilderTest.java
+++ b/tests/src/com/android/vcard/tests/VCardBuilderTest.java
@@ -44,9 +44,9 @@ public class VCardBuilderTest extends TestCase {
final String actual = builder.toString();
final String expectedCommon = ";CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:" +
- "=E0=A4=A8=E0=A5=87;;;;";
+ "=E0=A4=A8=E0=A5=87";
- final String expectedName = "N" + expectedCommon;
+ final String expectedName = "N" + expectedCommon + ";;;;";
final String expectedFullName = "FN" + expectedCommon;
assertTrue("Actual value:\n" + actual + " expected to contain\n" + expectedName +
diff --git a/tests/src/com/android/vcard/tests/VCardUtilsTests.java b/tests/src/com/android/vcard/tests/VCardUtilsTests.java
index 1ced881..d6365fb 100644
--- a/tests/src/com/android/vcard/tests/VCardUtilsTests.java
+++ b/tests/src/com/android/vcard/tests/VCardUtilsTests.java
@@ -117,4 +117,28 @@ public class VCardUtilsTests extends TestCase {
assertEquals("\"Already quoted\"",
VCardUtils.toStringAsV30ParamValue("\"Already quoted\"\""));
}
+
+ public void testAppearsLikeAndroidVCardQuotedPrintableByLength() {
+ assertFalse(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("="));
+ assertFalse(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=1"));
+ assertTrue(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=12"));
+ assertTrue(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=12="));
+ assertFalse(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=12=1"));
+ assertTrue(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=12=12"));
+ assertTrue(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=12=12="));
+ }
+
+ public void testAppearsLikeAndroidVCardQuotedPrintableByContent() {
+ assertTrue(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("==="));
+ assertTrue(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("===="));
+ assertTrue(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("======="));
+ assertTrue(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=12=12="));
+ assertTrue(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=12=34="));
+
+ assertFalse(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=123"));
+ assertFalse(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=123="));
+ assertFalse(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("_12="));
+ assertFalse(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=12_"));
+ assertFalse(VCardUtils.appearsLikeAndroidVCardQuotedPrintable("=12=34_56="));
+ }
}